···222222 <title>Two Main Types of Kernel Locks: Spinlocks and Semaphores</title>223223224224 <para>225225- There are two main types of kernel locks. The fundamental type225225+ There are three main types of kernel locks. The fundamental type226226 is the spinlock 227227 (<filename class="headerfile">include/asm/spinlock.h</filename>),228228 which is a very simple single-holder lock: if you can't get the ···230230 very small and fast, and can be used anywhere.231231 </para>232232 <para>233233- The second type is a semaphore233233+ The second type is a mutex234234+ (<filename class="headerfile">include/linux/mutex.h</filename>): it235235+ is like a spinlock, but you may block holding a mutex.236236+ If you can't lock a mutex, your task will suspend itself, and be woken237237+ up when the mutex is released. This means the CPU can do something238238+ else while you are waiting. There are many cases when you simply239239+ can't sleep (see <xref linkend="sleeping-things"/>), and so have to240240+ use a spinlock instead.241241+ </para>242242+ <para>243243+ The third type is a semaphore234244 (<filename class="headerfile">include/asm/semaphore.h</filename>): it235245 can have more than one holder at any time (the number decided at236246 initialization time), although it is most commonly used as a237237- single-holder lock (a mutex). If you can't get a semaphore,238238- your task will put itself on the queue, and be woken up when the239239- semaphore is released. This means the CPU will do something240240- else while you are waiting, but there are many cases when you241241- simply can't sleep (see <xref linkend="sleeping-things"/>), and so242242- have to use a spinlock instead.247247+ single-holder lock (a mutex). If you can't get a semaphore, your248248+ task will be suspended and later on woken up - just like for mutexes.243249 </para>244250 <para>245251 Neither type of lock is recursive: see
+135
Documentation/mutex-design.txt
···11+Generic Mutex Subsystem22+33+started by Ingo Molnar <mingo@redhat.com>44+55+ "Why on earth do we need a new mutex subsystem, and what's wrong66+ with semaphores?"77+88+firstly, there's nothing wrong with semaphores. But if the simpler99+mutex semantics are sufficient for your code, then there are a couple1010+of advantages of mutexes:1111+1212+ - 'struct mutex' is smaller on most architectures: .e.g on x86,1313+ 'struct semaphore' is 20 bytes, 'struct mutex' is 16 bytes.1414+ A smaller structure size means less RAM footprint, and better1515+ CPU-cache utilization.1616+1717+ - tighter code. On x86 i get the following .text sizes when1818+ switching all mutex-alike semaphores in the kernel to the mutex1919+ subsystem:2020+2121+ text data bss dec hex filename2222+ 3280380 868188 396860 4545428 455b94 vmlinux-semaphore2323+ 3255329 865296 396732 4517357 44eded vmlinux-mutex2424+2525+ that's 25051 bytes of code saved, or a 0.76% win - off the hottest2626+ codepaths of the kernel. (The .data savings are 2892 bytes, or 0.33%)2727+ Smaller code means better icache footprint, which is one of the2828+ major optimization goals in the Linux kernel currently.2929+3030+ - the mutex subsystem is slightly faster and has better scalability for3131+ contended workloads. On an 8-way x86 system, running a mutex-based3232+ kernel and testing creat+unlink+close (of separate, per-task files)3333+ in /tmp with 16 parallel tasks, the average number of ops/sec is:3434+3535+ Semaphores: Mutexes:3636+3737+ $ ./test-mutex V 16 10 $ ./test-mutex V 16 103838+ 8 CPUs, running 16 tasks. 8 CPUs, running 16 tasks.3939+ checking VFS performance. checking VFS performance.4040+ avg loops/sec: 34713 avg loops/sec: 841534141+ CPU utilization: 63% CPU utilization: 22%4242+4343+ i.e. in this workload, the mutex based kernel was 2.4 times faster4444+ than the semaphore based kernel, _and_ it also had 2.8 times less CPU4545+ utilization. (In terms of 'ops per CPU cycle', the semaphore kernel4646+ performed 551 ops/sec per 1% of CPU time used, while the mutex kernel4747+ performed 3825 ops/sec per 1% of CPU time used - it was 6.9 times4848+ more efficient.)4949+5050+ the scalability difference is visible even on a 2-way P4 HT box:5151+5252+ Semaphores: Mutexes:5353+5454+ $ ./test-mutex V 16 10 $ ./test-mutex V 16 105555+ 4 CPUs, running 16 tasks. 8 CPUs, running 16 tasks.5656+ checking VFS performance. checking VFS performance.5757+ avg loops/sec: 127659 avg loops/sec: 1810825858+ CPU utilization: 100% CPU utilization: 34%5959+6060+ (the straight performance advantage of mutexes is 41%, the per-cycle6161+ efficiency of mutexes is 4.1 times better.)6262+6363+ - there are no fastpath tradeoffs, the mutex fastpath is just as tight6464+ as the semaphore fastpath. On x86, the locking fastpath is 26565+ instructions:6666+6767+ c0377ccb <mutex_lock>:6868+ c0377ccb: f0 ff 08 lock decl (%eax)6969+ c0377cce: 78 0e js c0377cde <.text.lock.mutex>7070+ c0377cd0: c3 ret7171+7272+ the unlocking fastpath is equally tight:7373+7474+ c0377cd1 <mutex_unlock>:7575+ c0377cd1: f0 ff 00 lock incl (%eax)7676+ c0377cd4: 7e 0f jle c0377ce5 <.text.lock.mutex+0x7>7777+ c0377cd6: c3 ret7878+7979+ - 'struct mutex' semantics are well-defined and are enforced if8080+ CONFIG_DEBUG_MUTEXES is turned on. Semaphores on the other hand have8181+ virtually no debugging code or instrumentation. The mutex subsystem8282+ checks and enforces the following rules:8383+8484+ * - only one task can hold the mutex at a time8585+ * - only the owner can unlock the mutex8686+ * - multiple unlocks are not permitted8787+ * - recursive locking is not permitted8888+ * - a mutex object must be initialized via the API8989+ * - a mutex object must not be initialized via memset or copying9090+ * - task may not exit with mutex held9191+ * - memory areas where held locks reside must not be freed9292+ * - held mutexes must not be reinitialized9393+ * - mutexes may not be used in irq contexts9494+9595+ furthermore, there are also convenience features in the debugging9696+ code:9797+9898+ * - uses symbolic names of mutexes, whenever they are printed in debug output9999+ * - point-of-acquire tracking, symbolic lookup of function names100100+ * - list of all locks held in the system, printout of them101101+ * - owner tracking102102+ * - detects self-recursing locks and prints out all relevant info103103+ * - detects multi-task circular deadlocks and prints out all affected104104+ * locks and tasks (and only those tasks)105105+106106+Disadvantages107107+-------------108108+109109+The stricter mutex API means you cannot use mutexes the same way you110110+can use semaphores: e.g. they cannot be used from an interrupt context,111111+nor can they be unlocked from a different context that which acquired112112+it. [ I'm not aware of any other (e.g. performance) disadvantages from113113+using mutexes at the moment, please let me know if you find any. ]114114+115115+Implementation of mutexes116116+-------------------------117117+118118+'struct mutex' is the new mutex type, defined in include/linux/mutex.h119119+and implemented in kernel/mutex.c. It is a counter-based mutex with a120120+spinlock and a wait-list. The counter has 3 states: 1 for "unlocked",121121+0 for "locked" and negative numbers (usually -1) for "locked, potential122122+waiters queued".123123+124124+the APIs of 'struct mutex' have been streamlined:125125+126126+ DEFINE_MUTEX(name);127127+128128+ mutex_init(mutex);129129+130130+ void mutex_lock(struct mutex *lock);131131+ int mutex_lock_interruptible(struct mutex *lock);132132+ int mutex_trylock(struct mutex *lock);133133+ void mutex_unlock(struct mutex *lock);134134+ int mutex_is_locked(struct mutex *lock);135135+
+4
arch/i386/mm/pageattr.c
···222222{223223 if (PageHighMem(page))224224 return;225225+ if (!enable)226226+ mutex_debug_check_no_locks_freed(page_address(page),227227+ page_address(page+numpages));228228+225229 /* the return value is ignored - the calls cannot fail,226230 * large pages are disabled at boot time.227231 */
+6-6
arch/powerpc/platforms/cell/spufs/inode.c
···137137static void spufs_prune_dir(struct dentry *dir)138138{139139 struct dentry *dentry, *tmp;140140- down(&dir->d_inode->i_sem);140140+ mutex_lock(&dir->d_inode->i_mutex);141141 list_for_each_entry_safe(dentry, tmp, &dir->d_subdirs, d_child) {142142 spin_lock(&dcache_lock);143143 spin_lock(&dentry->d_lock);···154154 }155155 }156156 shrink_dcache_parent(dir);157157- up(&dir->d_inode->i_sem);157157+ mutex_unlock(&dir->d_inode->i_mutex);158158}159159160160static int spufs_rmdir(struct inode *root, struct dentry *dir_dentry)···162162 struct spu_context *ctx;163163164164 /* remove all entries */165165- down(&root->i_sem);165165+ mutex_lock(&root->i_mutex);166166 spufs_prune_dir(dir_dentry);167167- up(&root->i_sem);167167+ mutex_unlock(&root->i_mutex);168168169169 /* We have to give up the mm_struct */170170 ctx = SPUFS_I(dir_dentry->d_inode)->i_ctx;171171 spu_forget(ctx);172172173173- /* XXX Do we need to hold i_sem here ? */173173+ /* XXX Do we need to hold i_mutex here ? */174174 return simple_rmdir(root, dir_dentry);175175}176176···330330out_dput:331331 dput(dentry);332332out_dir:333333- up(&nd->dentry->d_inode->i_sem);333333+ mutex_unlock(&nd->dentry->d_inode->i_mutex);334334out:335335 return ret;336336}
+14-17
drivers/block/loop.c
···215215 unsigned offset, bv_offs;216216 int len, ret;217217218218- down(&mapping->host->i_sem);218218+ mutex_lock(&mapping->host->i_mutex);219219 index = pos >> PAGE_CACHE_SHIFT;220220 offset = pos & ((pgoff_t)PAGE_CACHE_SIZE - 1);221221 bv_offs = bvec->bv_offset;···278278 }279279 ret = 0;280280out:281281- up(&mapping->host->i_sem);281281+ mutex_unlock(&mapping->host->i_mutex);282282 return ret;283283unlock:284284 unlock_page(page);···527527 lo->lo_pending++;528528 loop_add_bio(lo, old_bio);529529 spin_unlock_irq(&lo->lo_lock);530530- up(&lo->lo_bh_mutex);530530+ complete(&lo->lo_bh_done);531531 return 0;532532533533out:534534 if (lo->lo_pending == 0)535535- up(&lo->lo_bh_mutex);535535+ complete(&lo->lo_bh_done);536536 spin_unlock_irq(&lo->lo_lock);537537 bio_io_error(old_bio, old_bio->bi_size);538538 return 0;···593593 lo->lo_pending = 1;594594595595 /*596596- * up sem, we are running596596+ * complete it, we are running597597 */598598- up(&lo->lo_sem);598598+ complete(&lo->lo_done);599599600600 for (;;) {601601 int pending;602602603603- /*604604- * interruptible just to not contribute to load avg605605- */606606- if (down_interruptible(&lo->lo_bh_mutex))603603+ if (wait_for_completion_interruptible(&lo->lo_bh_done))607604 continue;608605609606 spin_lock_irq(&lo->lo_lock);610607611608 /*612612- * could be upped because of tear-down, not pending work609609+ * could be completed because of tear-down, not pending work613610 */614611 if (unlikely(!lo->lo_pending)) {615612 spin_unlock_irq(&lo->lo_lock);···629632 break;630633 }631634632632- up(&lo->lo_sem);635635+ complete(&lo->lo_done);633636 return 0;634637}635638···840843 set_blocksize(bdev, lo_blocksize);841844842845 kernel_thread(loop_thread, lo, CLONE_KERNEL);843843- down(&lo->lo_sem);846846+ wait_for_completion(&lo->lo_done);844847 return 0;845848846849 out_putf:···906909 lo->lo_state = Lo_rundown;907910 lo->lo_pending--;908911 if (!lo->lo_pending)909909- up(&lo->lo_bh_mutex);912912+ complete(&lo->lo_bh_done);910913 spin_unlock_irq(&lo->lo_lock);911914912912- down(&lo->lo_sem);915915+ wait_for_completion(&lo->lo_done);913916914917 lo->lo_backing_file = NULL;915918···12861289 if (!lo->lo_queue)12871290 goto out_mem4;12881291 init_MUTEX(&lo->lo_ctl_mutex);12891289- init_MUTEX_LOCKED(&lo->lo_sem);12901290- init_MUTEX_LOCKED(&lo->lo_bh_mutex);12921292+ init_completion(&lo->lo_done);12931293+ init_completion(&lo->lo_bh_done);12911294 lo->lo_number = i;12921295 spin_lock_init(&lo->lo_lock);12931296 disk->major = LOOP_MAJOR;
+6-6
drivers/block/sx8.c
···2727#include <linux/time.h>2828#include <linux/hdreg.h>2929#include <linux/dma-mapping.h>3030+#include <linux/completion.h>3031#include <asm/io.h>3131-#include <asm/semaphore.h>3232#include <asm/uaccess.h>33333434#if 0···303303304304 struct work_struct fsm_task;305305306306- struct semaphore probe_sem;306306+ struct completion probe_comp;307307};308308309309struct carm_response {···13461346 }1347134713481348 case HST_PROBE_FINISHED:13491349- up(&host->probe_sem);13491349+ complete(&host->probe_comp);13501350 break;1351135113521352 case HST_ERROR:···16221622 host->flags = pci_dac ? FL_DAC : 0;16231623 spin_lock_init(&host->lock);16241624 INIT_WORK(&host->fsm_task, carm_fsm_task, host);16251625- init_MUTEX_LOCKED(&host->probe_sem);16251625+ init_completion(&host->probe_comp);1626162616271627 for (i = 0; i < ARRAY_SIZE(host->req); i++)16281628 host->req[i].tag = i;···16911691 if (rc)16921692 goto err_out_free_irq;1693169316941694- DPRINTK("waiting for probe_sem\n");16951695- down(&host->probe_sem);16941694+ DPRINTK("waiting for probe_comp\n");16951695+ wait_for_completion(&host->probe_comp);1696169616971697 printk(KERN_INFO "%s: pci %s, ports %d, io %lx, irq %u, major %d\n",16981698 host->name, pci_name(pdev), (int) CARM_MAX_PORTS,
···15621562 spin_unlock_irq (&dev->lock);1563156315641564 /* break link to dcache */15651565- down (&parent->i_sem);15651565+ mutex_lock (&parent->i_mutex);15661566 d_delete (dentry);15671567 dput (dentry);15681568- up (&parent->i_sem);15681568+ mutex_unlock (&parent->i_mutex);1569156915701570 /* fds may still be open */15711571 goto restart;
···229229 dentry->d_flags |= DCACHE_AUTOFS_PENDING;230230 d_add(dentry, NULL);231231232232- up(&dir->i_sem);232232+ mutex_unlock(&dir->i_mutex);233233 autofs_revalidate(dentry, nd);234234- down(&dir->i_sem);234234+ mutex_lock(&dir->i_mutex);235235236236 /*237237 * If we are still pending, check if we had to handle
···352352 * We need to protect against concurrent writers,353353 * which could cause livelocks in fsync_buffers_list354354 */355355- down(&mapping->host->i_sem);355355+ mutex_lock(&mapping->host->i_mutex);356356 err = file->f_op->fsync(file, file->f_dentry, datasync);357357 if (!ret)358358 ret = err;359359- up(&mapping->host->i_sem);359359+ mutex_unlock(&mapping->host->i_mutex);360360 err = filemap_fdatawait(mapping);361361 if (!ret)362362 ret = err;···23382338 __block_commit_write(inode,page,from,to);23392339 /*23402340 * No need to use i_size_read() here, the i_size23412341- * cannot change under us because we hold i_sem.23412341+ * cannot change under us because we hold i_mutex.23422342 */23432343 if (pos > inode->i_size) {23442344 i_size_write(inode, pos);
+3-3
fs/cifs/cifsfs.c
···860860 DeleteOplockQEntry(oplock_item);861861 /* can not grab inode sem here since it would862862 deadlock when oplock received on delete 863863- since vfs_unlink holds the i_sem across863863+ since vfs_unlink holds the i_mutex across864864 the call */865865- /* down(&inode->i_sem);*/865865+ /* mutex_lock(&inode->i_mutex);*/866866 if (S_ISREG(inode->i_mode)) {867867 rc = filemap_fdatawrite(inode->i_mapping);868868 if(CIFS_I(inode)->clientCanCacheRead == 0) {···871871 }872872 } else873873 rc = 0;874874- /* up(&inode->i_sem);*/874874+ /* mutex_unlock(&inode->i_mutex);*/875875 if (rc)876876 CIFS_I(inode)->write_behind_rc = rc;877877 cFYI(1,("Oplock flush inode %p rc %d",inode,rc));
+4-4
fs/cifs/inode.c
···10401040 }1041104110421042 /* can not grab this sem since kernel filesys locking documentation10431043- indicates i_sem may be taken by the kernel on lookup and rename10441044- which could deadlock if we grab the i_sem here as well */10451045-/* down(&direntry->d_inode->i_sem);*/10431043+ indicates i_mutex may be taken by the kernel on lookup and rename10441044+ which could deadlock if we grab the i_mutex here as well */10451045+/* mutex_lock(&direntry->d_inode->i_mutex);*/10461046 /* need to write out dirty pages here */10471047 if (direntry->d_inode->i_mapping) {10481048 /* do we need to lock inode until after invalidate completes···10661066 }10671067 }10681068 }10691069-/* up(&direntry->d_inode->i_sem); */10691069+/* mutex_unlock(&direntry->d_inode->i_mutex); */1070107010711071 kfree(full_path);10721072 FreeXid(xid);
···288288289289/*290290 * Only subdirectories count here. Files (CONFIGFS_NOT_PINNED) are291291- * attributes and are removed by rmdir(). We recurse, taking i_sem291291+ * attributes and are removed by rmdir(). We recurse, taking i_mutex292292 * on all children that are candidates for default detach. If the293293 * result is clean, then configfs_detach_group() will handle dropping294294- * i_sem. If there is an error, the caller will clean up the i_sem294294+ * i_mutex. If there is an error, the caller will clean up the i_mutex295295 * holders via configfs_detach_rollback().296296 */297297static int configfs_detach_prep(struct dentry *dentry)···309309 if (sd->s_type & CONFIGFS_NOT_PINNED)310310 continue;311311 if (sd->s_type & CONFIGFS_USET_DEFAULT) {312312- down(&sd->s_dentry->d_inode->i_sem);313313- /* Mark that we've taken i_sem */312312+ mutex_lock(&sd->s_dentry->d_inode->i_mutex);313313+ /* Mark that we've taken i_mutex */314314 sd->s_type |= CONFIGFS_USET_DROPPING;315315316316 ret = configfs_detach_prep(sd->s_dentry);···327327}328328329329/*330330- * Walk the tree, dropping i_sem wherever CONFIGFS_USET_DROPPING is330330+ * Walk the tree, dropping i_mutex wherever CONFIGFS_USET_DROPPING is331331 * set.332332 */333333static void configfs_detach_rollback(struct dentry *dentry)···341341342342 if (sd->s_type & CONFIGFS_USET_DROPPING) {343343 sd->s_type &= ~CONFIGFS_USET_DROPPING;344344- up(&sd->s_dentry->d_inode->i_sem);344344+ mutex_unlock(&sd->s_dentry->d_inode->i_mutex);345345 }346346 }347347 }···424424425425 /*426426 * From rmdir/unregister, a configfs_detach_prep() pass427427- * has taken our i_sem for us. Drop it.427427+ * has taken our i_mutex for us. Drop it.428428 * From mkdir/register cleanup, there is no sem held.429429 */430430 if (sd->s_type & CONFIGFS_USET_DROPPING)431431- up(&child->d_inode->i_sem);431431+ mutex_unlock(&child->d_inode->i_mutex);432432433433 d_delete(child);434434 dput(child);···493493 /* FYI, we're faking mkdir here494494 * I'm not sure we need this semaphore, as we're called495495 * from our parent's mkdir. That holds our parent's496496- * i_sem, so afaik lookup cannot continue through our496496+ * i_mutex, so afaik lookup cannot continue through our497497 * parent to find us, let alone mess with our tree.498498- * That said, taking our i_sem is closer to mkdir498498+ * That said, taking our i_mutex is closer to mkdir499499 * emulation, and shouldn't hurt. */500500- down(&dentry->d_inode->i_sem);500500+ mutex_lock(&dentry->d_inode->i_mutex);501501502502 for (i = 0; group->default_groups[i]; i++) {503503 new_group = group->default_groups[i];···507507 break;508508 }509509510510- up(&dentry->d_inode->i_sem);510510+ mutex_unlock(&dentry->d_inode->i_mutex);511511 }512512513513 if (ret)···856856 down_write(&configfs_rename_sem);857857 parent = item->parent->dentry;858858859859- down(&parent->d_inode->i_sem);859859+ mutex_lock(&parent->d_inode->i_mutex);860860861861 new_dentry = lookup_one_len(new_name, parent, strlen(new_name));862862 if (!IS_ERR(new_dentry)) {···872872 error = -EEXIST;873873 dput(new_dentry);874874 }875875- up(&parent->d_inode->i_sem);875875+ mutex_unlock(&parent->d_inode->i_mutex);876876 up_write(&configfs_rename_sem);877877878878 return error;···884884 struct dentry * dentry = file->f_dentry;885885 struct configfs_dirent * parent_sd = dentry->d_fsdata;886886887887- down(&dentry->d_inode->i_sem);887887+ mutex_lock(&dentry->d_inode->i_mutex);888888 file->private_data = configfs_new_dirent(parent_sd, NULL);889889- up(&dentry->d_inode->i_sem);889889+ mutex_unlock(&dentry->d_inode->i_mutex);890890891891 return file->private_data ? 0 : -ENOMEM;892892···897897 struct dentry * dentry = file->f_dentry;898898 struct configfs_dirent * cursor = file->private_data;899899900900- down(&dentry->d_inode->i_sem);900900+ mutex_lock(&dentry->d_inode->i_mutex);901901 list_del_init(&cursor->s_sibling);902902- up(&dentry->d_inode->i_sem);902902+ mutex_unlock(&dentry->d_inode->i_mutex);903903904904 release_configfs_dirent(cursor);905905···975975{976976 struct dentry * dentry = file->f_dentry;977977978978- down(&dentry->d_inode->i_sem);978978+ mutex_lock(&dentry->d_inode->i_mutex);979979 switch (origin) {980980 case 1:981981 offset += file->f_pos;···983983 if (offset >= 0)984984 break;985985 default:986986- up(&file->f_dentry->d_inode->i_sem);986986+ mutex_unlock(&file->f_dentry->d_inode->i_mutex);987987 return -EINVAL;988988 }989989 if (offset != file->f_pos) {···10071007 list_add_tail(&cursor->s_sibling, p);10081008 }10091009 }10101010- up(&dentry->d_inode->i_sem);10101010+ mutex_unlock(&dentry->d_inode->i_mutex);10111011 return offset;10121012}10131013···10371037 sd = configfs_sb->s_root->d_fsdata;10381038 link_group(to_config_group(sd->s_element), group);1039103910401040- down(&configfs_sb->s_root->d_inode->i_sem);10401040+ mutex_lock(&configfs_sb->s_root->d_inode->i_mutex);1041104110421042 name.name = group->cg_item.ci_name;10431043 name.len = strlen(name.name);···10571057 else10581058 d_delete(dentry);1059105910601060- up(&configfs_sb->s_root->d_inode->i_sem);10601060+ mutex_unlock(&configfs_sb->s_root->d_inode->i_mutex);1061106110621062 if (dentry) {10631063 dput(dentry);···10791079 return;10801080 }1081108110821082- down(&configfs_sb->s_root->d_inode->i_sem);10831083- down(&dentry->d_inode->i_sem);10821082+ mutex_lock(&configfs_sb->s_root->d_inode->i_mutex);10831083+ mutex_lock(&dentry->d_inode->i_mutex);10841084 if (configfs_detach_prep(dentry)) {10851085 printk(KERN_ERR "configfs: Tried to unregister non-empty subsystem!\n");10861086 }10871087 configfs_detach_group(&group->cg_item);10881088 dentry->d_inode->i_flags |= S_DEAD;10891089- up(&dentry->d_inode->i_sem);10891089+ mutex_unlock(&dentry->d_inode->i_mutex);1090109010911091 d_delete(dentry);1092109210931093- up(&configfs_sb->s_root->d_inode->i_sem);10931093+ mutex_unlock(&configfs_sb->s_root->d_inode->i_mutex);1094109410951095 dput(dentry);10961096
···122122123123/*124124 * Unhashes the dentry corresponding to given configfs_dirent125125- * Called with parent inode's i_sem held.125125+ * Called with parent inode's i_mutex held.126126 */127127void configfs_drop_dentry(struct configfs_dirent * sd, struct dentry * parent)128128{···145145 struct configfs_dirent * sd;146146 struct configfs_dirent * parent_sd = dir->d_fsdata;147147148148- down(&dir->d_inode->i_sem);148148+ mutex_lock(&dir->d_inode->i_mutex);149149 list_for_each_entry(sd, &parent_sd->s_children, s_sibling) {150150 if (!sd->s_element)151151 continue;···156156 break;157157 }158158 }159159- up(&dir->d_inode->i_sem);159159+ mutex_unlock(&dir->d_inode->i_mutex);160160}161161162162
+4-4
fs/debugfs/inode.c
···146146 }147147148148 *dentry = NULL;149149- down(&parent->d_inode->i_sem);149149+ mutex_lock(&parent->d_inode->i_mutex);150150 *dentry = lookup_one_len(name, parent, strlen(name));151151 if (!IS_ERR(dentry)) {152152 if ((mode & S_IFMT) == S_IFDIR)···155155 error = debugfs_create(parent->d_inode, *dentry, mode);156156 } else157157 error = PTR_ERR(dentry);158158- up(&parent->d_inode->i_sem);158158+ mutex_unlock(&parent->d_inode->i_mutex);159159160160 return error;161161}···273273 if (!parent || !parent->d_inode)274274 return;275275276276- down(&parent->d_inode->i_sem);276276+ mutex_lock(&parent->d_inode->i_mutex);277277 if (debugfs_positive(dentry)) {278278 if (dentry->d_inode) {279279 if (S_ISDIR(dentry->d_inode->i_mode))···283283 dput(dentry);284284 }285285 }286286- up(&parent->d_inode->i_sem);286286+ mutex_unlock(&parent->d_inode->i_mutex);287287 simple_release_fs(&debugfs_mount, &debugfs_mount_count);288288}289289EXPORT_SYMBOL_GPL(debugfs_remove);
+11-11
fs/devfs/base.c
···21622162 *21632163 * make sure that21642164 * d_instantiate always runs under lock21652165- * we release i_sem lock before going to sleep21652165+ * we release i_mutex lock before going to sleep21662166 *21672167 * unfortunately sometimes d_revalidate is called with21682168- * and sometimes without i_sem lock held. The following checks21682168+ * and sometimes without i_mutex lock held. The following checks21692169 * attempt to deduce when we need to add (and drop resp.) lock21702170 * here. This relies on current (2.6.2) calling coventions:21712171 *21722172- * lookup_hash is always run under i_sem and is passing NULL21722172+ * lookup_hash is always run under i_mutex and is passing NULL21732173 * as nd21742174 *21752175- * open(...,O_CREATE,...) calls _lookup_hash under i_sem21752175+ * open(...,O_CREATE,...) calls _lookup_hash under i_mutex21762176 * and sets flags to LOOKUP_OPEN|LOOKUP_CREATE21772177 *21782178 * all other invocations of ->d_revalidate seem to happen21792179- * outside of i_sem21792179+ * outside of i_mutex21802180 */21812181 need_lock = nd &&21822182 (!(nd->flags & LOOKUP_CREATE) || (nd->flags & LOOKUP_PARENT));2183218321842184 if (need_lock)21852185- down(&dir->i_sem);21852185+ mutex_lock(&dir->i_mutex);2186218621872187 if (is_devfsd_or_child(fs_info)) {21882188 devfs_handle_t de = lookup_info->de;···22212221 add_wait_queue(&lookup_info->wait_queue, &wait);22222222 read_unlock(&parent->u.dir.lock);22232223 /* at this point it is always (hopefully) locked */22242224- up(&dir->i_sem);22242224+ mutex_unlock(&dir->i_mutex);22252225 schedule();22262226- down(&dir->i_sem);22262226+ mutex_lock(&dir->i_mutex);22272227 /*22282228 * This does not need nor should remove wait from wait_queue.22292229 * Wait queue head is never reused - nothing is ever added to it···2238223822392239 out:22402240 if (need_lock)22412241- up(&dir->i_sem);22412241+ mutex_unlock(&dir->i_mutex);22422242 return 1;22432243} /* End Function devfs_d_revalidate_wait */22442244···22842284 /* Unlock directory semaphore, which will release any waiters. They22852285 will get the hashed dentry, and may be forced to wait for22862286 revalidation */22872287- up(&dir->i_sem);22872287+ mutex_unlock(&dir->i_mutex);22882288 wait_for_devfsd_finished(fs_info); /* If I'm not devfsd, must wait */22892289- down(&dir->i_sem); /* Grab it again because them's the rules */22892289+ mutex_lock(&dir->i_mutex); /* Grab it again because them's the rules */22902290 de = lookup_info.de;22912291 /* If someone else has been so kind as to make the inode, we go home22922292 early */
···5656 * lock_type is DIO_LOCKING for regular files on direct-IO-naive filesystems.5757 * This determines whether we need to do the fancy locking which prevents5858 * direct-IO from being able to read uninitialised disk blocks. If its zero5959- * (blockdev) this locking is not done, and if it is DIO_OWN_LOCKING i_sem is5959+ * (blockdev) this locking is not done, and if it is DIO_OWN_LOCKING i_mutex is6060 * not held for the entire direct write (taken briefly, initially, during a6161 * direct read though, but its never held for the duration of a direct-IO).6262 */···930930}931931932932/*933933- * Releases both i_sem and i_alloc_sem933933+ * Releases both i_mutex and i_alloc_sem934934 */935935static ssize_t936936direct_io_worker(int rw, struct kiocb *iocb, struct inode *inode, ···1062106210631063 /*10641064 * All block lookups have been performed. For READ requests10651065- * we can let i_sem go now that its achieved its purpose10651065+ * we can let i_mutex go now that its achieved its purpose10661066 * of protecting us from looking up uninitialized blocks.10671067 */10681068 if ((rw == READ) && (dio->lock_type == DIO_LOCKING))10691069- up(&dio->inode->i_sem);10691069+ mutex_unlock(&dio->inode->i_mutex);1070107010711071 /*10721072 * OK, all BIOs are submitted, so we can decrement bio_count to truly···11451145 * The locking rules are governed by the dio_lock_type parameter.11461146 *11471147 * DIO_NO_LOCKING (no locking, for raw block device access)11481148- * For writes, i_sem is not held on entry; it is never taken.11481148+ * For writes, i_mutex is not held on entry; it is never taken.11491149 *11501150 * DIO_LOCKING (simple locking for regular files)11511151- * For writes we are called under i_sem and return with i_sem held, even though11511151+ * For writes we are called under i_mutex and return with i_mutex held, even though11521152 * it is internally dropped.11531153- * For reads, i_sem is not held on entry, but it is taken and dropped before11531153+ * For reads, i_mutex is not held on entry, but it is taken and dropped before11541154 * returning.11551155 *11561156 * DIO_OWN_LOCKING (filesystem provides synchronisation and handling of11571157 * uninitialised data, allowing parallel direct readers and writers)11581158- * For writes we are called without i_sem, return without it, never touch it.11591159- * For reads, i_sem is held on entry and will be released before returning.11581158+ * For writes we are called without i_mutex, return without it, never touch it.11591159+ * For reads, i_mutex is held on entry and will be released before returning.11601160 *11611161 * Additional i_alloc_sem locking requirements described inline below.11621162 */···12141214 * For block device access DIO_NO_LOCKING is used,12151215 * neither readers nor writers do any locking at all12161216 * For regular files using DIO_LOCKING,12171217- * readers need to grab i_sem and i_alloc_sem12181218- * writers need to grab i_alloc_sem only (i_sem is already held)12171217+ * readers need to grab i_mutex and i_alloc_sem12181218+ * writers need to grab i_alloc_sem only (i_mutex is already held)12191219 * For regular files using DIO_OWN_LOCKING,12201220 * neither readers nor writers take any locks here12211221- * (i_sem is already held and release for writers here)12211221+ * (i_mutex is already held and release for writers here)12221222 */12231223 dio->lock_type = dio_lock_type;12241224 if (dio_lock_type != DIO_NO_LOCKING) {···1228122812291229 mapping = iocb->ki_filp->f_mapping;12301230 if (dio_lock_type != DIO_OWN_LOCKING) {12311231- down(&inode->i_sem);12311231+ mutex_lock(&inode->i_mutex);12321232 reader_with_isem = 1;12331233 }12341234···12401240 }1241124112421242 if (dio_lock_type == DIO_OWN_LOCKING) {12431243- up(&inode->i_sem);12431243+ mutex_unlock(&inode->i_mutex);12441244 reader_with_isem = 0;12451245 }12461246 }···1266126612671267out:12681268 if (reader_with_isem)12691269- up(&inode->i_sem);12691269+ mutex_unlock(&inode->i_mutex);12701270 if (rw & WRITE)12711271 current->flags &= ~PF_SYNCWRITE;12721272 return retval;
+8-8
fs/dquot.c
···100100 * operation is just reading pointers from inode (or not using them at all) the101101 * read lock is enough. If pointers are altered function must hold write lock102102 * (these locking rules also apply for S_NOQUOTA flag in the inode - note that103103- * for altering the flag i_sem is also needed). If operation is holding103103+ * for altering the flag i_mutex is also needed). If operation is holding104104 * reference to dquot in other way (e.g. quotactl ops) it must be guarded by105105 * dqonoff_sem.106106 * This locking assures that:···117117 * spinlock to internal buffers before writing.118118 *119119 * Lock ordering (including related VFS locks) is the following:120120- * i_sem > dqonoff_sem > iprune_sem > journal_lock > dqptr_sem >120120+ * i_mutex > dqonoff_sem > iprune_sem > journal_lock > dqptr_sem >121121 * > dquot->dq_lock > dqio_sem122122- * i_sem on quota files is special (it's below dqio_sem)122122+ * i_mutex on quota files is special (it's below dqio_sem)123123 */124124125125static DEFINE_SPINLOCK(dq_list_lock);···13691369 /* If quota was reenabled in the meantime, we have13701370 * nothing to do */13711371 if (!sb_has_quota_enabled(sb, cnt)) {13721372- down(&toputinode[cnt]->i_sem);13721372+ mutex_lock(&toputinode[cnt]->i_mutex);13731373 toputinode[cnt]->i_flags &= ~(S_IMMUTABLE |13741374 S_NOATIME | S_NOQUOTA);13751375 truncate_inode_pages(&toputinode[cnt]->i_data, 0);13761376- up(&toputinode[cnt]->i_sem);13761376+ mutex_unlock(&toputinode[cnt]->i_mutex);13771377 mark_inode_dirty(toputinode[cnt]);13781378 iput(toputinode[cnt]);13791379 }···14171417 write_inode_now(inode, 1);14181418 /* And now flush the block cache so that kernel sees the changes */14191419 invalidate_bdev(sb->s_bdev, 0);14201420- down(&inode->i_sem);14201420+ mutex_lock(&inode->i_mutex);14211421 down(&dqopt->dqonoff_sem);14221422 if (sb_has_quota_enabled(sb, type)) {14231423 error = -EBUSY;···14491449 goto out_file_init;14501450 }14511451 up(&dqopt->dqio_sem);14521452- up(&inode->i_sem);14521452+ mutex_unlock(&inode->i_mutex);14531453 set_enable_flags(dqopt, type);1454145414551455 add_dquot_ref(sb, type);···14701470 inode->i_flags |= oldflags;14711471 up_write(&dqopt->dqptr_sem);14721472 }14731473- up(&inode->i_sem);14731473+ mutex_unlock(&inode->i_mutex);14741474out_fmt:14751475 put_quota_format(fmt);14761476
···149149}150150151151/*152152- * inode->i_sem: don't care152152+ * inode->i_mutex: don't care153153 */154154static struct posix_acl *155155ext2_get_acl(struct inode *inode, int type)···211211}212212213213/*214214- * inode->i_sem: down214214+ * inode->i_mutex: down215215 */216216static int217217ext2_set_acl(struct inode *inode, int type, struct posix_acl *acl)···301301/*302302 * Initialize the ACLs of a new inode. Called from ext2_new_inode.303303 *304304- * dir->i_sem: down305305- * inode->i_sem: up (access to inode is still exclusive)304304+ * dir->i_mutex: down305305+ * inode->i_mutex: up (access to inode is still exclusive)306306 */307307int308308ext2_init_acl(struct inode *inode, struct inode *dir)···361361 * for directories) are added. There are no more bits available in the362362 * file mode.363363 *364364- * inode->i_sem: down364364+ * inode->i_mutex: down365365 */366366int367367ext2_acl_chmod(struct inode *inode)
+1-1
fs/ext2/ext2.h
···5353#ifdef CONFIG_EXT2_FS_XATTR5454 /*5555 * Extended attributes can be read independently of the main file5656- * data. Taking i_sem even when reading would cause contention5656+ * data. Taking i_mutex even when reading would cause contention5757 * between readers of EAs and writers of regular file data, so5858 * instead we synchronize on xattr_sem when reading or changing5959 * EAs.
···152152/*153153 * Inode operation get_posix_acl().154154 *155155- * inode->i_sem: don't care155155+ * inode->i_mutex: don't care156156 */157157static struct posix_acl *158158ext3_get_acl(struct inode *inode, int type)···216216/*217217 * Set the access or default ACL of an inode.218218 *219219- * inode->i_sem: down unless called from ext3_new_inode219219+ * inode->i_mutex: down unless called from ext3_new_inode220220 */221221static int222222ext3_set_acl(handle_t *handle, struct inode *inode, int type,···306306/*307307 * Initialize the ACLs of a new inode. Called from ext3_new_inode.308308 *309309- * dir->i_sem: down310310- * inode->i_sem: up (access to inode is still exclusive)309309+ * dir->i_mutex: down310310+ * inode->i_mutex: up (access to inode is still exclusive)311311 */312312int313313ext3_init_acl(handle_t *handle, struct inode *inode, struct inode *dir)···368368 * for directories) are added. There are no more bits available in the369369 * file mode.370370 *371371- * inode->i_sem: down371371+ * inode->i_mutex: down372372 */373373int374374ext3_acl_chmod(struct inode *inode)
···14151415 * This will never trigger with sane page sizes. leave it in14161416 * anyway, since I'm thinking about how to merge larger writes14171417 * (the current idea is to poke a thread that does the actual14181418- * I/O and starts by doing a down(&inode->i_sem). then we14181418+ * I/O and starts by doing a mutex_lock(&inode->i_mutex). then we14191419 * would need to get the page cache pages and have a list of14201420 * I/O requests and do write-merging here.14211421 * -- prumpf
+2-2
fs/jfs/jfs_incore.h
···5858 /*5959 * rdwrlock serializes xtree between reads & writes and synchronizes6060 * changes to special inodes. It's use would be redundant on6161- * directories since the i_sem taken in the VFS is sufficient.6161+ * directories since the i_mutex taken in the VFS is sufficient.6262 */6363 struct rw_semaphore rdwrlock;6464 /*···6868 * inode is blocked in txBegin or TxBeginAnon6969 */7070 struct semaphore commit_sem;7171- /* xattr_sem allows us to access the xattrs without taking i_sem */7171+ /* xattr_sem allows us to access the xattrs without taking i_mutex */7272 struct rw_semaphore xattr_sem;7373 lid_t xtlid; /* lid of xtree lock on directory */7474#ifdef CONFIG_JFS_POSIX_ACL
+4-4
fs/libfs.c
···74747575loff_t dcache_dir_lseek(struct file *file, loff_t offset, int origin)7676{7777- down(&file->f_dentry->d_inode->i_sem);7777+ mutex_lock(&file->f_dentry->d_inode->i_mutex);7878 switch (origin) {7979 case 1:8080 offset += file->f_pos;···8282 if (offset >= 0)8383 break;8484 default:8585- up(&file->f_dentry->d_inode->i_sem);8585+ mutex_unlock(&file->f_dentry->d_inode->i_mutex);8686 return -EINVAL;8787 }8888 if (offset != file->f_pos) {···106106 spin_unlock(&dcache_lock);107107 }108108 }109109- up(&file->f_dentry->d_inode->i_sem);109109+ mutex_unlock(&file->f_dentry->d_inode->i_mutex);110110 return offset;111111}112112···356356357357 /*358358 * No need to use i_size_read() here, the i_size359359- * cannot change under us because we hold the i_sem.359359+ * cannot change under us because we hold the i_mutex.360360 */361361 if (pos > inode->i_size)362362 i_size_write(inode, pos);
+41-41
fs/namei.c
···438438 struct dentry * result;439439 struct inode *dir = parent->d_inode;440440441441- down(&dir->i_sem);441441+ mutex_lock(&dir->i_mutex);442442 /*443443 * First re-do the cached lookup just in case it was created444444 * while we waited for the directory semaphore..···464464 else465465 result = dentry;466466 }467467- up(&dir->i_sem);467467+ mutex_unlock(&dir->i_mutex);468468 return result;469469 }470470···472472 * Uhhuh! Nasty case: the cache was re-populated while473473 * we waited on the semaphore. Need to revalidate.474474 */475475- up(&dir->i_sem);475475+ mutex_unlock(&dir->i_mutex);476476 if (result->d_op && result->d_op->d_revalidate) {477477 if (!result->d_op->d_revalidate(result, nd) && !d_invalidate(result)) {478478 dput(result);···13661366 struct dentry *p;1367136713681368 if (p1 == p2) {13691369- down(&p1->d_inode->i_sem);13691369+ mutex_lock(&p1->d_inode->i_mutex);13701370 return NULL;13711371 }13721372···1374137413751375 for (p = p1; p->d_parent != p; p = p->d_parent) {13761376 if (p->d_parent == p2) {13771377- down(&p2->d_inode->i_sem);13781378- down(&p1->d_inode->i_sem);13771377+ mutex_lock(&p2->d_inode->i_mutex);13781378+ mutex_lock(&p1->d_inode->i_mutex);13791379 return p;13801380 }13811381 }1382138213831383 for (p = p2; p->d_parent != p; p = p->d_parent) {13841384 if (p->d_parent == p1) {13851385- down(&p1->d_inode->i_sem);13861386- down(&p2->d_inode->i_sem);13851385+ mutex_lock(&p1->d_inode->i_mutex);13861386+ mutex_lock(&p2->d_inode->i_mutex);13871387 return p;13881388 }13891389 }1390139013911391- down(&p1->d_inode->i_sem);13921392- down(&p2->d_inode->i_sem);13911391+ mutex_lock(&p1->d_inode->i_mutex);13921392+ mutex_lock(&p2->d_inode->i_mutex);13931393 return NULL;13941394}1395139513961396void unlock_rename(struct dentry *p1, struct dentry *p2)13971397{13981398- up(&p1->d_inode->i_sem);13981398+ mutex_unlock(&p1->d_inode->i_mutex);13991399 if (p1 != p2) {14001400- up(&p2->d_inode->i_sem);14001400+ mutex_unlock(&p2->d_inode->i_mutex);14011401 up(&p1->d_inode->i_sb->s_vfs_rename_sem);14021402 }14031403}···1563156315641564 dir = nd->dentry;15651565 nd->flags &= ~LOOKUP_PARENT;15661566- down(&dir->d_inode->i_sem);15661566+ mutex_lock(&dir->d_inode->i_mutex);15671567 path.dentry = lookup_hash(nd);15681568 path.mnt = nd->mnt;1569156915701570do_last:15711571 error = PTR_ERR(path.dentry);15721572 if (IS_ERR(path.dentry)) {15731573- up(&dir->d_inode->i_sem);15731573+ mutex_unlock(&dir->d_inode->i_mutex);15741574 goto exit;15751575 }15761576···15791579 if (!IS_POSIXACL(dir->d_inode))15801580 mode &= ~current->fs->umask;15811581 error = vfs_create(dir->d_inode, path.dentry, mode, nd);15821582- up(&dir->d_inode->i_sem);15821582+ mutex_unlock(&dir->d_inode->i_mutex);15831583 dput(nd->dentry);15841584 nd->dentry = path.dentry;15851585 if (error)···15931593 /*15941594 * It already exists.15951595 */15961596- up(&dir->d_inode->i_sem);15961596+ mutex_unlock(&dir->d_inode->i_mutex);1597159715981598 error = -EEXIST;15991599 if (flag & O_EXCL)···16651665 goto exit;16661666 }16671667 dir = nd->dentry;16681668- down(&dir->d_inode->i_sem);16681668+ mutex_lock(&dir->d_inode->i_mutex);16691669 path.dentry = lookup_hash(nd);16701670 path.mnt = nd->mnt;16711671 __putname(nd->last.name);···16801680 * Simple function to lookup and return a dentry and create it16811681 * if it doesn't exist. Is SMP-safe.16821682 *16831683- * Returns with nd->dentry->d_inode->i_sem locked.16831683+ * Returns with nd->dentry->d_inode->i_mutex locked.16841684 */16851685struct dentry *lookup_create(struct nameidata *nd, int is_dir)16861686{16871687 struct dentry *dentry = ERR_PTR(-EEXIST);1688168816891689- down(&nd->dentry->d_inode->i_sem);16891689+ mutex_lock(&nd->dentry->d_inode->i_mutex);16901690 /*16911691 * Yucky last component or no last component at all?16921692 * (foo/., foo/.., /////)···17841784 }17851785 dput(dentry);17861786 }17871787- up(&nd.dentry->d_inode->i_sem);17871787+ mutex_unlock(&nd.dentry->d_inode->i_mutex);17881788 path_release(&nd);17891789out:17901790 putname(tmp);···18361836 error = vfs_mkdir(nd.dentry->d_inode, dentry, mode);18371837 dput(dentry);18381838 }18391839- up(&nd.dentry->d_inode->i_sem);18391839+ mutex_unlock(&nd.dentry->d_inode->i_mutex);18401840 path_release(&nd);18411841out:18421842 putname(tmp);···1885188518861886 DQUOT_INIT(dir);1887188718881888- down(&dentry->d_inode->i_sem);18881888+ mutex_lock(&dentry->d_inode->i_mutex);18891889 dentry_unhash(dentry);18901890 if (d_mountpoint(dentry))18911891 error = -EBUSY;···18971897 dentry->d_inode->i_flags |= S_DEAD;18981898 }18991899 }19001900- up(&dentry->d_inode->i_sem);19001900+ mutex_unlock(&dentry->d_inode->i_mutex);19011901 if (!error) {19021902 d_delete(dentry);19031903 }···19321932 error = -EBUSY;19331933 goto exit1;19341934 }19351935- down(&nd.dentry->d_inode->i_sem);19351935+ mutex_lock(&nd.dentry->d_inode->i_mutex);19361936 dentry = lookup_hash(&nd);19371937 error = PTR_ERR(dentry);19381938 if (!IS_ERR(dentry)) {19391939 error = vfs_rmdir(nd.dentry->d_inode, dentry);19401940 dput(dentry);19411941 }19421942- up(&nd.dentry->d_inode->i_sem);19421942+ mutex_unlock(&nd.dentry->d_inode->i_mutex);19431943exit1:19441944 path_release(&nd);19451945exit:···1959195919601960 DQUOT_INIT(dir);1961196119621962- down(&dentry->d_inode->i_sem);19621962+ mutex_lock(&dentry->d_inode->i_mutex);19631963 if (d_mountpoint(dentry))19641964 error = -EBUSY;19651965 else {···19671967 if (!error)19681968 error = dir->i_op->unlink(dir, dentry);19691969 }19701970- up(&dentry->d_inode->i_sem);19701970+ mutex_unlock(&dentry->d_inode->i_mutex);1971197119721972 /* We don't d_delete() NFS sillyrenamed files--they still exist. */19731973 if (!error && !(dentry->d_flags & DCACHE_NFSFS_RENAMED)) {···1979197919801980/*19811981 * Make sure that the actual truncation of the file will occur outside its19821982- * directory's i_sem. Truncate can take a long time if there is a lot of19821982+ * directory's i_mutex. Truncate can take a long time if there is a lot of19831983 * writeout happening, and we don't want to prevent access to the directory19841984 * while waiting on the I/O.19851985 */···20012001 error = -EISDIR;20022002 if (nd.last_type != LAST_NORM)20032003 goto exit1;20042004- down(&nd.dentry->d_inode->i_sem);20042004+ mutex_lock(&nd.dentry->d_inode->i_mutex);20052005 dentry = lookup_hash(&nd);20062006 error = PTR_ERR(dentry);20072007 if (!IS_ERR(dentry)) {···20152015 exit2:20162016 dput(dentry);20172017 }20182018- up(&nd.dentry->d_inode->i_sem);20182018+ mutex_unlock(&nd.dentry->d_inode->i_mutex);20192019 if (inode)20202020 iput(inode); /* truncate the inode here */20212021exit1:···20752075 error = vfs_symlink(nd.dentry->d_inode, dentry, from, S_IALLUGO);20762076 dput(dentry);20772077 }20782078- up(&nd.dentry->d_inode->i_sem);20782078+ mutex_unlock(&nd.dentry->d_inode->i_mutex);20792079 path_release(&nd);20802080out:20812081 putname(to);···21132113 if (error)21142114 return error;2115211521162116- down(&old_dentry->d_inode->i_sem);21162116+ mutex_lock(&old_dentry->d_inode->i_mutex);21172117 DQUOT_INIT(dir);21182118 error = dir->i_op->link(old_dentry, dir, new_dentry);21192119- up(&old_dentry->d_inode->i_sem);21192119+ mutex_unlock(&old_dentry->d_inode->i_mutex);21202120 if (!error)21212121 fsnotify_create(dir, new_dentry->d_name.name);21222122 return error;···21572157 error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);21582158 dput(new_dentry);21592159 }21602160- up(&nd.dentry->d_inode->i_sem);21602160+ mutex_unlock(&nd.dentry->d_inode->i_mutex);21612161out_release:21622162 path_release(&nd);21632163out:···21782178 * sb->s_vfs_rename_sem. We might be more accurate, but that's another21792179 * story.21802180 * c) we have to lock _three_ objects - parents and victim (if it exists).21812181- * And that - after we got ->i_sem on parents (until then we don't know21812181+ * And that - after we got ->i_mutex on parents (until then we don't know21822182 * whether the target exists). Solution: try to be smart with locking21832183 * order for inodes. We rely on the fact that tree topology may change21842184 * only under ->s_vfs_rename_sem _and_ that parent of the object we···21952195 * stuff into VFS), but the former is not going away. Solution: the same21962196 * trick as in rmdir().21972197 * e) conversion from fhandle to dentry may come in the wrong moment - when21982198- * we are removing the target. Solution: we will have to grab ->i_sem21982198+ * we are removing the target. Solution: we will have to grab ->i_mutex21992199 * in the fhandle_to_dentry code. [FIXME - current nfsfh.c relies on22002200- * ->i_sem on parents, which works but leads to some truely excessive22002200+ * ->i_mutex on parents, which works but leads to some truely excessive22012201 * locking].22022202 */22032203static int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,···2222222222232223 target = new_dentry->d_inode;22242224 if (target) {22252225- down(&target->i_sem);22252225+ mutex_lock(&target->i_mutex);22262226 dentry_unhash(new_dentry);22272227 }22282228 if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry))···22322232 if (target) {22332233 if (!error)22342234 target->i_flags |= S_DEAD;22352235- up(&target->i_sem);22352235+ mutex_unlock(&target->i_mutex);22362236 if (d_unhashed(new_dentry))22372237 d_rehash(new_dentry);22382238 dput(new_dentry);···22552255 dget(new_dentry);22562256 target = new_dentry->d_inode;22572257 if (target)22582258- down(&target->i_sem);22582258+ mutex_lock(&target->i_mutex);22592259 if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry))22602260 error = -EBUSY;22612261 else···22662266 d_move(old_dentry, new_dentry);22672267 }22682268 if (target)22692269- up(&target->i_sem);22692269+ mutex_unlock(&target->i_mutex);22702270 dput(new_dentry);22712271 return error;22722272}
···194194 spin_unlock(&inode->i_lock);195195 /* Ensure consistent page alignment of the data.196196 * Note: assumes we have exclusive access to this mapping either197197- * through inode->i_sem or some other mechanism.197197+ * through inode->i_mutex or some other mechanism.198198 */199199 if (page->index == 0)200200 invalidate_inode_pages2_range(inode->i_mapping, PAGE_CACHE_SIZE, -1);···573573574574loff_t nfs_llseek_dir(struct file *filp, loff_t offset, int origin)575575{576576- down(&filp->f_dentry->d_inode->i_sem);576576+ mutex_lock(&filp->f_dentry->d_inode->i_mutex);577577 switch (origin) {578578 case 1:579579 offset += filp->f_pos;···589589 ((struct nfs_open_context *)filp->private_data)->dir_cookie = 0;590590 }591591out:592592- up(&filp->f_dentry->d_inode->i_sem);592592+ mutex_unlock(&filp->f_dentry->d_inode->i_mutex);593593 return offset;594594}595595···10011001 openflags &= ~(O_CREAT|O_TRUNC);1002100210031003 /*10041004- * Note: we're not holding inode->i_sem and so may be racing with10041004+ * Note: we're not holding inode->i_mutex and so may be racing with10051005 * operations that change the directory. We therefore save the10061006 * change attribute *before* we do the RPC call.10071007 */···10511051 return dentry;10521052 if (!desc->plus || !(entry->fattr->valid & NFS_ATTR_FATTR))10531053 return NULL;10541054- /* Note: caller is already holding the dir->i_sem! */10541054+ /* Note: caller is already holding the dir->i_mutex! */10551055 dentry = d_alloc(parent, &name);10561056 if (dentry == NULL)10571057 return NULL;
+10-10
fs/nfsd/nfs4recover.c
···121121static void122122nfsd4_sync_rec_dir(void)123123{124124- down(&rec_dir.dentry->d_inode->i_sem);124124+ mutex_lock(&rec_dir.dentry->d_inode->i_mutex);125125 nfsd_sync_dir(rec_dir.dentry);126126- up(&rec_dir.dentry->d_inode->i_sem);126126+ mutex_unlock(&rec_dir.dentry->d_inode->i_mutex);127127}128128129129int···143143 nfs4_save_user(&uid, &gid);144144145145 /* lock the parent */146146- down(&rec_dir.dentry->d_inode->i_sem);146146+ mutex_lock(&rec_dir.dentry->d_inode->i_mutex);147147148148 dentry = lookup_one_len(dname, rec_dir.dentry, HEXDIR_LEN-1);149149 if (IS_ERR(dentry)) {···159159out_put:160160 dput(dentry);161161out_unlock:162162- up(&rec_dir.dentry->d_inode->i_sem);162162+ mutex_unlock(&rec_dir.dentry->d_inode->i_mutex);163163 if (status == 0) {164164 clp->cl_firststate = 1;165165 nfsd4_sync_rec_dir();···259259 printk("nfsd4: non-file found in client recovery directory\n");260260 return -EINVAL;261261 }262262- down(&dir->d_inode->i_sem);262262+ mutex_lock(&dir->d_inode->i_mutex);263263 status = vfs_unlink(dir->d_inode, dentry);264264- up(&dir->d_inode->i_sem);264264+ mutex_unlock(&dir->d_inode->i_mutex);265265 return status;266266}267267···274274 * any regular files anyway, just in case the directory was created by275275 * a kernel from the future.... */276276 nfsd4_list_rec_dir(dentry, nfsd4_remove_clid_file);277277- down(&dir->d_inode->i_sem);277277+ mutex_lock(&dir->d_inode->i_mutex);278278 status = vfs_rmdir(dir->d_inode, dentry);279279- up(&dir->d_inode->i_sem);279279+ mutex_unlock(&dir->d_inode->i_mutex);280280 return status;281281}282282···288288289289 dprintk("NFSD: nfsd4_unlink_clid_dir. name %.*s\n", namlen, name);290290291291- down(&rec_dir.dentry->d_inode->i_sem);291291+ mutex_lock(&rec_dir.dentry->d_inode->i_mutex);292292 dentry = lookup_one_len(name, rec_dir.dentry, namlen);293293- up(&rec_dir.dentry->d_inode->i_sem);293293+ mutex_unlock(&rec_dir.dentry->d_inode->i_mutex);294294 if (IS_ERR(dentry)) {295295 status = PTR_ERR(dentry);296296 return status;
···15321532 * NOTE to self: No changes in the attribute list are required to move from15331533 * a resident to a non-resident attribute.15341534 *15351535- * Locking: - The caller must hold i_sem on the inode.15351535+ * Locking: - The caller must hold i_mutex on the inode.15361536 */15371537int ntfs_attr_make_non_resident(ntfs_inode *ni, const u32 data_size)15381538{···17281728 /*17291729 * This needs to be last since the address space operations ->readpage17301730 * and ->writepage can run concurrently with us as they are not17311731- * serialized on i_sem. Note, we are not allowed to fail once we flip17311731+ * serialized on i_mutex. Note, we are not allowed to fail once we flip17321732 * this switch, which is another reason to do this last.17331733 */17341734 NInoSetNonResident(ni);
+4-4
fs/ntfs/dir.c
···6969 * work but we don't care for how quickly one can access them. This also fixes7070 * the dcache aliasing issues.7171 *7272- * Locking: - Caller must hold i_sem on the directory.7272+ * Locking: - Caller must hold i_mutex on the directory.7373 * - Each page cache page in the index allocation mapping must be7474 * locked whilst being accessed otherwise we may find a corrupt7575 * page due to it being under ->writepage at the moment which···10851085 * While this will return the names in random order this doesn't matter for10861086 * ->readdir but OTOH results in a faster ->readdir.10871087 *10881088- * VFS calls ->readdir without BKL but with i_sem held. This protects the VFS10881088+ * VFS calls ->readdir without BKL but with i_mutex held. This protects the VFS10891089 * parts (e.g. ->f_pos and ->i_size, and it also protects against directory10901090 * modifications).10911091 *10921092- * Locking: - Caller must hold i_sem on the directory.10921092+ * Locking: - Caller must hold i_mutex on the directory.10931093 * - Each page cache page in the index allocation mapping must be10941094 * locked whilst being accessed otherwise we may find a corrupt10951095 * page due to it being under ->writepage at the moment which···15201520 * Note: In the past @filp could be NULL so we ignore it as we don't need it15211521 * anyway.15221522 *15231523- * Locking: Caller must hold i_sem on the inode.15231523+ * Locking: Caller must hold i_mutex on the inode.15241524 *15251525 * TODO: We should probably also write all attribute/index inodes associated15261526 * with this inode but since we have no simple way of getting to them we ignore
+9-9
fs/ntfs/file.c
···106106 * this is the case, the necessary zeroing will also have happened and that all107107 * metadata is self-consistent.108108 *109109- * Locking: i_sem on the vfs inode corrseponsind to the ntfs inode @ni must be109109+ * Locking: i_mutex on the vfs inode corrseponsind to the ntfs inode @ni must be110110 * held by the caller.111111 */112112static int ntfs_attr_extend_initialized(ntfs_inode *ni, const s64 new_init_size,···473473 * @bytes: number of bytes to be written474474 *475475 * This is called for non-resident attributes from ntfs_file_buffered_write()476476- * with i_sem held on the inode (@pages[0]->mapping->host). There are476476+ * with i_mutex held on the inode (@pages[0]->mapping->host). There are477477 * @nr_pages pages in @pages which are locked but not kmap()ped. The source478478 * data has not yet been copied into the @pages.479479 * ···16371637 * @pos: byte position in file at which the write begins16381638 * @bytes: number of bytes to be written16391639 *16401640- * This is called from ntfs_file_buffered_write() with i_sem held on the inode16401640+ * This is called from ntfs_file_buffered_write() with i_mutex held on the inode16411641 * (@pages[0]->mapping->host). There are @nr_pages pages in @pages which are16421642 * locked but not kmap()ped. The source data has already been copied into the16431643 * @page. ntfs_prepare_pages_for_non_resident_write() has been called before···18141814/**18151815 * ntfs_file_buffered_write -18161816 *18171817- * Locking: The vfs is holding ->i_sem on the inode.18171817+ * Locking: The vfs is holding ->i_mutex on the inode.18181818 */18191819static ssize_t ntfs_file_buffered_write(struct kiocb *iocb,18201820 const struct iovec *iov, unsigned long nr_segs,···2196219621972197 BUG_ON(iocb->ki_pos != pos);2198219821992199- down(&inode->i_sem);21992199+ mutex_lock(&inode->i_mutex);22002200 ret = ntfs_file_aio_write_nolock(iocb, &local_iov, 1, &iocb->ki_pos);22012201- up(&inode->i_sem);22012201+ mutex_unlock(&inode->i_mutex);22022202 if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) {22032203 int err = sync_page_range(inode, mapping, pos, ret);22042204 if (err < 0)···22212221 struct kiocb kiocb;22222222 ssize_t ret;2223222322242224- down(&inode->i_sem);22242224+ mutex_lock(&inode->i_mutex);22252225 init_sync_kiocb(&kiocb, file);22262226 ret = ntfs_file_aio_write_nolock(&kiocb, iov, nr_segs, ppos);22272227 if (ret == -EIOCBQUEUED)22282228 ret = wait_on_sync_kiocb(&kiocb);22292229- up(&inode->i_sem);22292229+ mutex_unlock(&inode->i_mutex);22302230 if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) {22312231 int err = sync_page_range(inode, mapping, *ppos - ret, ret);22322232 if (err < 0)···22692269 * Note: In the past @filp could be NULL so we ignore it as we don't need it22702270 * anyway.22712271 *22722272- * Locking: Caller must hold i_sem on the inode.22722272+ * Locking: Caller must hold i_mutex on the inode.22732273 *22742274 * TODO: We should probably also write all attribute/index inodes associated22752275 * with this inode but since we have no simple way of getting to them we ignore
+3-3
fs/ntfs/index.c
···3232 * Allocate a new index context, initialize it with @idx_ni and return it.3333 * Return NULL if allocation failed.3434 *3535- * Locking: Caller must hold i_sem on the index inode.3535+ * Locking: Caller must hold i_mutex on the index inode.3636 */3737ntfs_index_context *ntfs_index_ctx_get(ntfs_inode *idx_ni)3838{···5050 *5151 * Release the index context @ictx, releasing all associated resources.5252 *5353- * Locking: Caller must hold i_sem on the index inode.5353+ * Locking: Caller must hold i_mutex on the index inode.5454 */5555void ntfs_index_ctx_put(ntfs_index_context *ictx)5656{···106106 * or ntfs_index_entry_write() before the call to ntfs_index_ctx_put() to107107 * ensure that the changes are written to disk.108108 *109109- * Locking: - Caller must hold i_sem on the index inode.109109+ * Locking: - Caller must hold i_mutex on the index inode.110110 * - Each page cache page in the index allocation mapping must be111111 * locked whilst being accessed otherwise we may find a corrupt112112 * page due to it being under ->writepage at the moment which
+4-4
fs/ntfs/inode.c
···21252125 ntfs_inode *ni = NTFS_I(vi);21262126 if (NInoIndexAllocPresent(ni)) {21272127 struct inode *bvi = NULL;21282128- down(&vi->i_sem);21282128+ mutex_lock(&vi->i_mutex);21292129 if (atomic_read(&vi->i_count) == 2) {21302130 bvi = ni->itype.index.bmp_ino;21312131 if (bvi)21322132 ni->itype.index.bmp_ino = NULL;21332133 }21342134- up(&vi->i_sem);21342134+ mutex_unlock(&vi->i_mutex);21352135 if (bvi)21362136 iput(bvi);21372137 }···23112311 *23122312 * Returns 0 on success or -errno on error.23132313 *23142314- * Called with ->i_sem held. In all but one case ->i_alloc_sem is held for23142314+ * Called with ->i_mutex held. In all but one case ->i_alloc_sem is held for23152315 * writing. The only case in the kernel where ->i_alloc_sem is not held is23162316 * mm/filemap.c::generic_file_buffered_write() where vmtruncate() is called23172317 * with the current i_size as the offset. The analogous place in NTFS is in···28312831 * We also abort all changes of user, group, and mode as we do not implement28322832 * the NTFS ACLs yet.28332833 *28342834- * Called with ->i_sem held. For the ATTR_SIZE (i.e. ->truncate) case, also28342834+ * Called with ->i_mutex held. For the ATTR_SIZE (i.e. ->truncate) case, also28352835 * called with ->i_alloc_sem held for writing.28362836 *28372837 * Basically this is a copy of generic notify_change() and inode_setattr()
+3-3
fs/ntfs/namei.c
···9696 * name. We then convert the name to the current NLS code page, and proceed9797 * searching for a dentry with this name, etc, as in case 2), above.9898 *9999- * Locking: Caller must hold i_sem on the directory.9999+ * Locking: Caller must hold i_mutex on the directory.100100 */101101static struct dentry *ntfs_lookup(struct inode *dir_ino, struct dentry *dent,102102 struct nameidata *nd)···254254 nls_name.hash = full_name_hash(nls_name.name, nls_name.len);255255256256 /*257257- * Note: No need for dent->d_lock lock as i_sem is held on the257257+ * Note: No need for dent->d_lock lock as i_mutex is held on the258258 * parent inode.259259 */260260···374374 * The code is based on the ext3 ->get_parent() implementation found in375375 * fs/ext3/namei.c::ext3_get_parent().376376 *377377- * Note: ntfs_get_parent() is called with @child_dent->d_inode->i_sem down.377377+ * Note: ntfs_get_parent() is called with @child_dent->d_inode->i_mutex down.378378 *379379 * Return the dentry of the parent directory on success or the error code on380380 * error (IS_ERR() is true).
+3-3
fs/ntfs/quota.c
···4848 ntfs_error(vol->sb, "Quota inodes are not open.");4949 return FALSE;5050 }5151- down(&vol->quota_q_ino->i_sem);5151+ mutex_lock(&vol->quota_q_ino->i_mutex);5252 ictx = ntfs_index_ctx_get(NTFS_I(vol->quota_q_ino));5353 if (!ictx) {5454 ntfs_error(vol->sb, "Failed to get index context.");···9898 ntfs_index_entry_mark_dirty(ictx);9999set_done:100100 ntfs_index_ctx_put(ictx);101101- up(&vol->quota_q_ino->i_sem);101101+ mutex_unlock(&vol->quota_q_ino->i_mutex);102102 /*103103 * We set the flag so we do not try to mark the quotas out of date104104 * again on remount.···110110err_out:111111 if (ictx)112112 ntfs_index_ctx_put(ictx);113113- up(&vol->quota_q_ino->i_sem);113113+ mutex_unlock(&vol->quota_q_ino->i_mutex);114114 return FALSE;115115}116116
+8-8
fs/ntfs/super.c
···12131213 * Find the inode number for the hibernation file by looking up the12141214 * filename hiberfil.sys in the root directory.12151215 */12161216- down(&vol->root_ino->i_sem);12161216+ mutex_lock(&vol->root_ino->i_mutex);12171217 mref = ntfs_lookup_inode_by_name(NTFS_I(vol->root_ino), hiberfil, 12,12181218 &name);12191219- up(&vol->root_ino->i_sem);12191219+ mutex_unlock(&vol->root_ino->i_mutex);12201220 if (IS_ERR_MREF(mref)) {12211221 ret = MREF_ERR(mref);12221222 /* If the file does not exist, Windows is not hibernated. */···13071307 * Find the inode number for the quota file by looking up the filename13081308 * $Quota in the extended system files directory $Extend.13091309 */13101310- down(&vol->extend_ino->i_sem);13101310+ mutex_lock(&vol->extend_ino->i_mutex);13111311 mref = ntfs_lookup_inode_by_name(NTFS_I(vol->extend_ino), Quota, 6,13121312 &name);13131313- up(&vol->extend_ino->i_sem);13131313+ mutex_unlock(&vol->extend_ino->i_mutex);13141314 if (IS_ERR_MREF(mref)) {13151315 /*13161316 * If the file does not exist, quotas are disabled and have···13901390 * Find the inode number for the transaction log file by looking up the13911391 * filename $UsnJrnl in the extended system files directory $Extend.13921392 */13931393- down(&vol->extend_ino->i_sem);13931393+ mutex_lock(&vol->extend_ino->i_mutex);13941394 mref = ntfs_lookup_inode_by_name(NTFS_I(vol->extend_ino), UsnJrnl, 8,13951395 &name);13961396- up(&vol->extend_ino->i_sem);13961396+ mutex_unlock(&vol->extend_ino->i_mutex);13971397 if (IS_ERR_MREF(mref)) {13981398 /*13991399 * If the file does not exist, transaction logging is disabled,···23122312 if (!list_empty(&sb->s_dirty)) {23132313 const char *s1, *s2;2314231423152315- down(&vol->mft_ino->i_sem);23152315+ mutex_lock(&vol->mft_ino->i_mutex);23162316 truncate_inode_pages(vol->mft_ino->i_mapping, 0);23172317- up(&vol->mft_ino->i_sem);23172317+ mutex_unlock(&vol->mft_ino->i_mutex);23182318 write_inode_now(vol->mft_ino, 1);23192319 if (!list_empty(&sb->s_dirty)) {23202320 static const char *_s1 = "inodes";
+12-12
fs/ocfs2/alloc.c
···966966 mlog_entry("start_blk = %"MLFu64", num_clusters = %u\n", start_blk,967967 num_clusters);968968969969- BUG_ON(!down_trylock(&tl_inode->i_sem));969969+ BUG_ON(mutex_trylock(&tl_inode->i_mutex));970970971971 start_cluster = ocfs2_blocks_to_clusters(osb->sb, start_blk);972972···11081108 return status;11091109}1110111011111111-/* Expects you to already be holding tl_inode->i_sem */11111111+/* Expects you to already be holding tl_inode->i_mutex */11121112static int __ocfs2_flush_truncate_log(struct ocfs2_super *osb)11131113{11141114 int status;···1123112311241124 mlog_entry_void();1125112511261126- BUG_ON(!down_trylock(&tl_inode->i_sem));11261126+ BUG_ON(mutex_trylock(&tl_inode->i_mutex));1127112711281128 di = (struct ocfs2_dinode *) tl_bh->b_data;11291129 tl = &di->id2.i_dealloc;···11981198 int status;11991199 struct inode *tl_inode = osb->osb_tl_inode;1200120012011201- down(&tl_inode->i_sem);12011201+ mutex_lock(&tl_inode->i_mutex);12021202 status = __ocfs2_flush_truncate_log(osb);12031203- up(&tl_inode->i_sem);12031203+ mutex_unlock(&tl_inode->i_mutex);1204120412051205 return status;12061206}···13631363 mlog(0, "cleanup %u records from %"MLFu64"\n", num_recs,13641364 tl_copy->i_blkno);1365136513661366- down(&tl_inode->i_sem);13661366+ mutex_lock(&tl_inode->i_mutex);13671367 for(i = 0; i < num_recs; i++) {13681368 if (ocfs2_truncate_log_needs_flush(osb)) {13691369 status = __ocfs2_flush_truncate_log(osb);···13951395 }1396139613971397bail_up:13981398- up(&tl_inode->i_sem);13981398+ mutex_unlock(&tl_inode->i_mutex);1399139914001400 mlog_exit(status);14011401 return status;···1840184018411841 mlog(0, "clusters_to_del = %u in this pass\n", clusters_to_del);1842184218431843- down(&tl_inode->i_sem);18431843+ mutex_lock(&tl_inode->i_mutex);18441844 tl_sem = 1;18451845 /* ocfs2_truncate_log_needs_flush guarantees us at least one18461846 * record is free for use. If there isn't any, we flush to get···18751875 goto bail;18761876 }1877187718781878- up(&tl_inode->i_sem);18781878+ mutex_unlock(&tl_inode->i_mutex);18791879 tl_sem = 0;1880188018811881 ocfs2_commit_trans(handle);···18901890 ocfs2_schedule_truncate_log_flush(osb, 1);1891189118921892 if (tl_sem)18931893- up(&tl_inode->i_sem);18931893+ mutex_unlock(&tl_inode->i_mutex);1894189418951895 if (handle)18961896 ocfs2_commit_trans(handle);···19941994 goto bail;19951995 }1996199619971997- down(&ext_alloc_inode->i_sem);19971997+ mutex_lock(&ext_alloc_inode->i_mutex);19981998 (*tc)->tc_ext_alloc_inode = ext_alloc_inode;1999199920002000 status = ocfs2_meta_lock(ext_alloc_inode,···20262026 if (tc->tc_ext_alloc_locked)20272027 ocfs2_meta_unlock(tc->tc_ext_alloc_inode, 1);2028202820292029- up(&tc->tc_ext_alloc_inode->i_sem);20292029+ mutex_unlock(&tc->tc_ext_alloc_inode->i_mutex);20302030 iput(tc->tc_ext_alloc_inode);20312031 }20322032
+1-1
fs/ocfs2/cluster/nodemanager.c
···653653 struct config_group *o2hb_group = NULL, *ret = NULL;654654 void *defs = NULL;655655656656- /* this runs under the parent dir's i_sem; there can be only656656+ /* this runs under the parent dir's i_mutex; there can be only657657 * one caller in here at a time */658658 if (o2nm_single_cluster)659659 goto out; /* ENOSPC */
+2-2
fs/ocfs2/dir.c
···202202}203203204204/*205205- * NOTE: this should always be called with parent dir i_sem taken.205205+ * NOTE: this should always be called with parent dir i_mutex taken.206206 */207207int ocfs2_find_files_on_disk(const char *name,208208 int namelen,···245245 * Return 0 if the name does not exist246246 * Return -EEXIST if the directory contains the name247247 *248248- * Callers should have i_sem + a cluster lock on dir248248+ * Callers should have i_mutex + a cluster lock on dir249249 */250250int ocfs2_check_dir_for_entry(struct inode *dir,251251 const char *name,
+4-4
fs/ocfs2/file.c
···492492 }493493494494 /* blocks peope in read/write from reading our allocation495495- * until we're done changing it. We depend on i_sem to block495495+ * until we're done changing it. We depend on i_mutex to block496496 * other extend/truncate calls while we're here. Ordering wrt497497 * start_trans is important here -- always do it before! */498498 down_write(&OCFS2_I(inode)->ip_alloc_sem);···958958 filp->f_flags &= ~O_DIRECT;959959#endif960960961961- down(&inode->i_sem);962962- /* to match setattr's i_sem -> i_alloc_sem -> rw_lock ordering */961961+ mutex_lock(&inode->i_mutex);962962+ /* to match setattr's i_mutex -> i_alloc_sem -> rw_lock ordering */963963 if (filp->f_flags & O_DIRECT) {964964 have_alloc_sem = 1;965965 down_read(&inode->i_alloc_sem);···11231123 up_read(&inode->i_alloc_sem);11241124 if (rw_level != -1) 11251125 ocfs2_rw_unlock(inode, rw_level);11261126- up(&inode->i_sem);11261126+ mutex_unlock(&inode->i_mutex);1127112711281128 mlog_exit(ret);11291129 return ret;
+6-6
fs/ocfs2/inode.c
···485485 goto bail;486486 }487487488488- down(&inode_alloc_inode->i_sem);488488+ mutex_lock(&inode_alloc_inode->i_mutex);489489 status = ocfs2_meta_lock(inode_alloc_inode, NULL, &inode_alloc_bh, 1);490490 if (status < 0) {491491- up(&inode_alloc_inode->i_sem);491491+ mutex_unlock(&inode_alloc_inode->i_mutex);492492493493 mlog_errno(status);494494 goto bail;···536536 ocfs2_commit_trans(handle);537537bail_unlock:538538 ocfs2_meta_unlock(inode_alloc_inode, 1);539539- up(&inode_alloc_inode->i_sem);539539+ mutex_unlock(&inode_alloc_inode->i_mutex);540540 brelse(inode_alloc_bh);541541bail:542542 iput(inode_alloc_inode);···567567 /* Lock the orphan dir. The lock will be held for the entire568568 * delete_inode operation. We do this now to avoid races with569569 * recovery completion on other nodes. */570570- down(&orphan_dir_inode->i_sem);570570+ mutex_lock(&orphan_dir_inode->i_mutex);571571 status = ocfs2_meta_lock(orphan_dir_inode, NULL, &orphan_dir_bh, 1);572572 if (status < 0) {573573- up(&orphan_dir_inode->i_sem);573573+ mutex_unlock(&orphan_dir_inode->i_mutex);574574575575 mlog_errno(status);576576 goto bail;···593593594594bail_unlock_dir:595595 ocfs2_meta_unlock(orphan_dir_inode, 1);596596- up(&orphan_dir_inode->i_sem);596596+ mutex_unlock(&orphan_dir_inode->i_mutex);597597 brelse(orphan_dir_bh);598598bail:599599 iput(orphan_dir_inode);
+7-7
fs/ocfs2/journal.c
···216216 atomic_inc(&inode->i_count);217217218218 /* we're obviously changing it... */219219- down(&inode->i_sem);219219+ mutex_lock(&inode->i_mutex);220220221221 /* sanity check */222222 BUG_ON(OCFS2_I(inode)->ip_handle);···241241 OCFS2_I(inode)->ip_handle = NULL;242242 list_del_init(&OCFS2_I(inode)->ip_handle_list);243243244244- up(&inode->i_sem);244244+ mutex_unlock(&inode->i_mutex);245245 iput(inode);246246 }247247}···14331433 goto out;14341434 }1435143514361436- down(&orphan_dir_inode->i_sem);14361436+ mutex_lock(&orphan_dir_inode->i_mutex);14371437 status = ocfs2_meta_lock(orphan_dir_inode, NULL, NULL, 0);14381438 if (status < 0) {14391439- up(&orphan_dir_inode->i_sem);14391439+ mutex_unlock(&orphan_dir_inode->i_mutex);14401440 mlog_errno(status);14411441 goto out;14421442 }···14511451 if (!bh)14521452 status = -EINVAL;14531453 if (status < 0) {14541454- up(&orphan_dir_inode->i_sem);14541454+ mutex_unlock(&orphan_dir_inode->i_mutex);14551455 if (bh)14561456 brelse(bh);14571457 mlog_errno(status);···1465146514661466 if (!ocfs2_check_dir_entry(orphan_dir_inode,14671467 de, bh, local)) {14681468- up(&orphan_dir_inode->i_sem);14681468+ mutex_unlock(&orphan_dir_inode->i_mutex);14691469 status = -EINVAL;14701470 mlog_errno(status);14711471 brelse(bh);···15091509 }15101510 brelse(bh);15111511 }15121512- up(&orphan_dir_inode->i_sem);15121512+ mutex_unlock(&orphan_dir_inode->i_mutex);1513151315141514 ocfs2_meta_unlock(orphan_dir_inode, 0);15151515 have_disk_lock = 0;
+3-3
fs/ocfs2/localalloc.c
···334334 goto bail;335335 }336336337337- down(&inode->i_sem);337337+ mutex_lock(&inode->i_mutex);338338339339 status = ocfs2_read_block(osb, OCFS2_I(inode)->ip_blkno,340340 &alloc_bh, 0, inode);···367367 brelse(alloc_bh);368368369369 if (inode) {370370- up(&inode->i_sem);370370+ mutex_unlock(&inode->i_mutex);371371 iput(inode);372372 }373373···446446447447/*448448 * make sure we've got at least bitswanted contiguous bits in the449449- * local alloc. You lose them when you drop i_sem.449449+ * local alloc. You lose them when you drop i_mutex.450450 *451451 * We will add ourselves to the transaction passed in, but may start452452 * our own in order to shift windows.
+1-1
fs/ocfs2/super.c
···169169 */170170static void ocfs2_write_super(struct super_block *sb)171171{172172- if (down_trylock(&sb->s_lock) == 0)172172+ if (mutex_trylock(&sb->s_lock) != 0)173173 BUG();174174 sb->s_dirt = 0;175175}
···4444 * is considered a noninteractive wait:4545 */4646 prepare_to_wait(PIPE_WAIT(*inode), &wait, TASK_INTERRUPTIBLE|TASK_NONINTERACTIVE);4747- up(PIPE_SEM(*inode));4747+ mutex_unlock(PIPE_MUTEX(*inode));4848 schedule();4949 finish_wait(PIPE_WAIT(*inode), &wait);5050- down(PIPE_SEM(*inode));5050+ mutex_lock(PIPE_MUTEX(*inode));5151}52525353static inline int···136136137137 do_wakeup = 0;138138 ret = 0;139139- down(PIPE_SEM(*inode));139139+ mutex_lock(PIPE_MUTEX(*inode));140140 info = inode->i_pipe;141141 for (;;) {142142 int bufs = info->nrbufs;···200200 }201201 pipe_wait(inode);202202 }203203- up(PIPE_SEM(*inode));203203+ mutex_unlock(PIPE_MUTEX(*inode));204204 /* Signal writers asynchronously that there is more room. */205205 if (do_wakeup) {206206 wake_up_interruptible(PIPE_WAIT(*inode));···237237238238 do_wakeup = 0;239239 ret = 0;240240- down(PIPE_SEM(*inode));240240+ mutex_lock(PIPE_MUTEX(*inode));241241 info = inode->i_pipe;242242243243 if (!PIPE_READERS(*inode)) {···341341 PIPE_WAITING_WRITERS(*inode)--;342342 }343343out:344344- up(PIPE_SEM(*inode));344344+ mutex_unlock(PIPE_MUTEX(*inode));345345 if (do_wakeup) {346346 wake_up_interruptible(PIPE_WAIT(*inode));347347 kill_fasync(PIPE_FASYNC_READERS(*inode), SIGIO, POLL_IN);···381381382382 switch (cmd) {383383 case FIONREAD:384384- down(PIPE_SEM(*inode));384384+ mutex_lock(PIPE_MUTEX(*inode));385385 info = inode->i_pipe;386386 count = 0;387387 buf = info->curbuf;···390390 count += info->bufs[buf].len;391391 buf = (buf+1) & (PIPE_BUFFERS-1);392392 }393393- up(PIPE_SEM(*inode));393393+ mutex_unlock(PIPE_MUTEX(*inode));394394 return put_user(count, (int __user *)arg);395395 default:396396 return -EINVAL;···433433static int434434pipe_release(struct inode *inode, int decr, int decw)435435{436436- down(PIPE_SEM(*inode));436436+ mutex_lock(PIPE_MUTEX(*inode));437437 PIPE_READERS(*inode) -= decr;438438 PIPE_WRITERS(*inode) -= decw;439439 if (!PIPE_READERS(*inode) && !PIPE_WRITERS(*inode)) {···443443 kill_fasync(PIPE_FASYNC_READERS(*inode), SIGIO, POLL_IN);444444 kill_fasync(PIPE_FASYNC_WRITERS(*inode), SIGIO, POLL_OUT);445445 }446446- up(PIPE_SEM(*inode));446446+ mutex_unlock(PIPE_MUTEX(*inode));447447448448 return 0;449449}···454454 struct inode *inode = filp->f_dentry->d_inode;455455 int retval;456456457457- down(PIPE_SEM(*inode));457457+ mutex_lock(PIPE_MUTEX(*inode));458458 retval = fasync_helper(fd, filp, on, PIPE_FASYNC_READERS(*inode));459459- up(PIPE_SEM(*inode));459459+ mutex_unlock(PIPE_MUTEX(*inode));460460461461 if (retval < 0)462462 return retval;···471471 struct inode *inode = filp->f_dentry->d_inode;472472 int retval;473473474474- down(PIPE_SEM(*inode));474474+ mutex_lock(PIPE_MUTEX(*inode));475475 retval = fasync_helper(fd, filp, on, PIPE_FASYNC_WRITERS(*inode));476476- up(PIPE_SEM(*inode));476476+ mutex_unlock(PIPE_MUTEX(*inode));477477478478 if (retval < 0)479479 return retval;···488488 struct inode *inode = filp->f_dentry->d_inode;489489 int retval;490490491491- down(PIPE_SEM(*inode));491491+ mutex_lock(PIPE_MUTEX(*inode));492492493493 retval = fasync_helper(fd, filp, on, PIPE_FASYNC_READERS(*inode));494494495495 if (retval >= 0)496496 retval = fasync_helper(fd, filp, on, PIPE_FASYNC_WRITERS(*inode));497497498498- up(PIPE_SEM(*inode));498498+ mutex_unlock(PIPE_MUTEX(*inode));499499500500 if (retval < 0)501501 return retval;···534534{535535 /* We could have perhaps used atomic_t, but this and friends536536 below are the only places. So it doesn't seem worthwhile. */537537- down(PIPE_SEM(*inode));537537+ mutex_lock(PIPE_MUTEX(*inode));538538 PIPE_READERS(*inode)++;539539- up(PIPE_SEM(*inode));539539+ mutex_unlock(PIPE_MUTEX(*inode));540540541541 return 0;542542}···544544static int545545pipe_write_open(struct inode *inode, struct file *filp)546546{547547- down(PIPE_SEM(*inode));547547+ mutex_lock(PIPE_MUTEX(*inode));548548 PIPE_WRITERS(*inode)++;549549- up(PIPE_SEM(*inode));549549+ mutex_unlock(PIPE_MUTEX(*inode));550550551551 return 0;552552}···554554static int555555pipe_rdwr_open(struct inode *inode, struct file *filp)556556{557557- down(PIPE_SEM(*inode));557557+ mutex_lock(PIPE_MUTEX(*inode));558558 if (filp->f_mode & FMODE_READ)559559 PIPE_READERS(*inode)++;560560 if (filp->f_mode & FMODE_WRITE)561561 PIPE_WRITERS(*inode)++;562562- up(PIPE_SEM(*inode));562562+ mutex_unlock(PIPE_MUTEX(*inode));563563564564 return 0;565565}
+3-3
fs/quota.c
···168168 sync_blockdev(sb->s_bdev);169169170170 /* Now when everything is written we can discard the pagecache so171171- * that userspace sees the changes. We need i_sem and so we could171171+ * that userspace sees the changes. We need i_mutex and so we could172172 * not do it inside dqonoff_sem. Moreover we need to be carefull173173 * about races with quotaoff() (that is the reason why we have own174174 * reference to inode). */···184184 up(&sb_dqopt(sb)->dqonoff_sem);185185 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {186186 if (discard[cnt]) {187187- down(&discard[cnt]->i_sem);187187+ mutex_lock(&discard[cnt]->i_mutex);188188 truncate_inode_pages(&discard[cnt]->i_data, 0);189189- up(&discard[cnt]->i_sem);189189+ mutex_unlock(&discard[cnt]->i_mutex);190190 iput(discard[cnt]);191191 }192192 }
+2-2
fs/read_write.c
···3333 long long retval;3434 struct inode *inode = file->f_mapping->host;35353636- down(&inode->i_sem);3636+ mutex_lock(&inode->i_mutex);3737 switch (origin) {3838 case 2:3939 offset += inode->i_size;···4949 }5050 retval = offset;5151 }5252- up(&inode->i_sem);5252+ mutex_unlock(&inode->i_mutex);5353 return retval;5454}5555
+2-2
fs/readdir.c
···3030 if (res)3131 goto out;32323333- down(&inode->i_sem);3333+ mutex_lock(&inode->i_mutex);3434 res = -ENOENT;3535 if (!IS_DEADDIR(inode)) {3636 res = file->f_op->readdir(file, buf, filler);3737 file_accessed(file);3838 }3939- up(&inode->i_sem);3939+ mutex_unlock(&inode->i_mutex);4040out:4141 return res;4242}
+5-5
fs/reiserfs/file.c
···4949 }50505151 reiserfs_write_lock(inode->i_sb);5252- down(&inode->i_sem);5252+ mutex_lock(&inode->i_mutex);5353 /* freeing preallocation only involves relogging blocks that5454 * are already in the current transaction. preallocation gets5555 * freed at the end of each transaction, so it is impossible for···100100 err = reiserfs_truncate_file(inode, 0);101101 }102102 out:103103- up(&inode->i_sem);103103+ mutex_unlock(&inode->i_mutex);104104 reiserfs_write_unlock(inode->i_sb);105105 return err;106106}···13421342 if (unlikely(!access_ok(VERIFY_READ, buf, count)))13431343 return -EFAULT;1344134413451345- down(&inode->i_sem); // locks the entire file for just us13451345+ mutex_lock(&inode->i_mutex); // locks the entire file for just us1346134613471347 pos = *ppos;13481348···15321532 generic_osync_inode(inode, file->f_mapping,15331533 OSYNC_METADATA | OSYNC_DATA);1534153415351535- up(&inode->i_sem);15351535+ mutex_unlock(&inode->i_mutex);15361536 reiserfs_async_progress_wait(inode->i_sb);15371537 return (already_written != 0) ? already_written : res;1538153815391539 out:15401540- up(&inode->i_sem); // unlock the file on exit.15401540+ mutex_unlock(&inode->i_mutex); // unlock the file on exit.15411541 return res;15421542}15431543
+7-7
fs/reiserfs/inode.c
···40404141 /* The = 0 happens when we abort creating a new inode for some reason like lack of space.. */4242 if (!(inode->i_state & I_NEW) && INODE_PKEY(inode)->k_objectid != 0) { /* also handles bad_inode case */4343- down(&inode->i_sem);4343+ mutex_lock(&inode->i_mutex);44444545 reiserfs_delete_xattrs(inode);46464747 if (journal_begin(&th, inode->i_sb, jbegin_count)) {4848- up(&inode->i_sem);4848+ mutex_unlock(&inode->i_mutex);4949 goto out;5050 }5151 reiserfs_update_inode_transaction(inode);···5959 DQUOT_FREE_INODE(inode);60606161 if (journal_end(&th, inode->i_sb, jbegin_count)) {6262- up(&inode->i_sem);6262+ mutex_unlock(&inode->i_mutex);6363 goto out;6464 }65656666- up(&inode->i_sem);6666+ mutex_unlock(&inode->i_mutex);67676868 /* check return value from reiserfs_delete_object after6969 * ending the transaction···551551552552 /* we don't have to make sure the conversion did not happen while553553 ** we were locking the page because anyone that could convert554554- ** must first take i_sem.554554+ ** must first take i_mutex.555555 **556556 ** We must fix the tail page for writing because it might have buffers557557 ** that are mapped, but have a block number of 0. This indicates tail···586586 BUG_ON(!th->t_trans_id);587587588588#ifdef REISERFS_PREALLOCATE589589- if (!(flags & GET_BLOCK_NO_ISEM)) {589589+ if (!(flags & GET_BLOCK_NO_IMUX)) {590590 return reiserfs_new_unf_blocknrs2(th, inode, allocated_block_nr,591591 path, block);592592 }···23182318 /* this is where we fill in holes in the file. */23192319 if (use_get_block) {23202320 retval = reiserfs_get_block(inode, block, bh_result,23212321- GET_BLOCK_CREATE | GET_BLOCK_NO_ISEM23212321+ GET_BLOCK_CREATE | GET_BLOCK_NO_IMUX23222322 | GET_BLOCK_NO_DANGLE);23232323 if (!retval) {23242324 if (!buffer_mapped(bh_result)
+2-2
fs/reiserfs/ioctl.c
···120120 /* we need to make sure nobody is changing the file size beneath121121 ** us122122 */123123- down(&inode->i_sem);123123+ mutex_lock(&inode->i_mutex);124124125125 write_from = inode->i_size & (blocksize - 1);126126 /* if we are on a block boundary, we are already unpacked. */···156156 page_cache_release(page);157157158158 out:159159- up(&inode->i_sem);159159+ mutex_unlock(&inode->i_mutex);160160 reiserfs_write_unlock(inode->i_sb);161161 return retval;162162}
···205205 1) * p_s_sb->s_blocksize;206206 pos1 = pos;207207208208- // we are protected by i_sem. The tail can not disapper, not208208+ // we are protected by i_mutex. The tail can not disapper, not209209 // append can be done either210210 // we are in truncate or packing tail in file_release211211
+17-17
fs/reiserfs/xattr.c
···6767 goto out;6868 } else if (!xaroot->d_inode) {6969 int err;7070- down(&privroot->d_inode->i_sem);7070+ mutex_lock(&privroot->d_inode->i_mutex);7171 err =7272 privroot->d_inode->i_op->mkdir(privroot->d_inode, xaroot,7373 0700);7474- up(&privroot->d_inode->i_sem);7474+ mutex_unlock(&privroot->d_inode->i_mutex);75757676 if (err) {7777 dput(xaroot);···219219 } else if (flags & XATTR_REPLACE || flags & FL_READONLY) {220220 goto out;221221 } else {222222- /* inode->i_sem is down, so nothing else can try to create222222+ /* inode->i_mutex is down, so nothing else can try to create223223 * the same xattr */224224 err = xadir->d_inode->i_op->create(xadir->d_inode, xafile,225225 0700 | S_IFREG, NULL);···268268 * and don't mess with f->f_pos, but the idea is the same. Do some269269 * action on each and every entry in the directory.270270 *271271- * we're called with i_sem held, so there are no worries about the directory271271+ * we're called with i_mutex held, so there are no worries about the directory272272 * changing underneath us.273273 */274274static int __xattr_readdir(struct file *filp, void *dirent, filldir_t filldir)···426426 int res = -ENOTDIR;427427 if (!file->f_op || !file->f_op->readdir)428428 goto out;429429- down(&inode->i_sem);429429+ mutex_lock(&inode->i_mutex);430430// down(&inode->i_zombie);431431 res = -ENOENT;432432 if (!IS_DEADDIR(inode)) {···435435 unlock_kernel();436436 }437437// up(&inode->i_zombie);438438- up(&inode->i_sem);438438+ mutex_unlock(&inode->i_mutex);439439 out:440440 return res;441441}···480480/* Generic extended attribute operations that can be used by xa plugins */481481482482/*483483- * inode->i_sem: down483483+ * inode->i_mutex: down484484 */485485int486486reiserfs_xattr_set(struct inode *inode, const char *name, const void *buffer,···535535 /* Resize it so we're ok to write there */536536 newattrs.ia_size = buffer_size;537537 newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME;538538- down(&xinode->i_sem);538538+ mutex_lock(&xinode->i_mutex);539539 err = notify_change(fp->f_dentry, &newattrs);540540 if (err)541541 goto out_filp;···598598 }599599600600 out_filp:601601- up(&xinode->i_sem);601601+ mutex_unlock(&xinode->i_mutex);602602 fput(fp);603603604604 out:···606606}607607608608/*609609- * inode->i_sem: down609609+ * inode->i_mutex: down610610 */611611int612612reiserfs_xattr_get(const struct inode *inode, const char *name, void *buffer,···793793794794}795795796796-/* This is called w/ inode->i_sem downed */796796+/* This is called w/ inode->i_mutex downed */797797int reiserfs_delete_xattrs(struct inode *inode)798798{799799 struct file *fp;···946946947947/*948948 * Inode operation getxattr()949949- * Preliminary locking: we down dentry->d_inode->i_sem949949+ * Preliminary locking: we down dentry->d_inode->i_mutex950950 */951951ssize_t952952reiserfs_getxattr(struct dentry * dentry, const char *name, void *buffer,···970970/*971971 * Inode operation setxattr()972972 *973973- * dentry->d_inode->i_sem down973973+ * dentry->d_inode->i_mutex down974974 */975975int976976reiserfs_setxattr(struct dentry *dentry, const char *name, const void *value,···10081008/*10091009 * Inode operation removexattr()10101010 *10111011- * dentry->d_inode->i_sem down10111011+ * dentry->d_inode->i_mutex down10121012 */10131013int reiserfs_removexattr(struct dentry *dentry, const char *name)10141014{···10911091/*10921092 * Inode operation listxattr()10931093 *10941094- * Preliminary locking: we down dentry->d_inode->i_sem10941094+ * Preliminary locking: we down dentry->d_inode->i_mutex10951095 */10961096ssize_t reiserfs_listxattr(struct dentry * dentry, char *buffer, size_t size)10971097{···12891289 if (!IS_ERR(dentry)) {12901290 if (!(mount_flags & MS_RDONLY) && !dentry->d_inode) {12911291 struct inode *inode = dentry->d_parent->d_inode;12921292- down(&inode->i_sem);12921292+ mutex_lock(&inode->i_mutex);12931293 err = inode->i_op->mkdir(inode, dentry, 0700);12941294- up(&inode->i_sem);12941294+ mutex_unlock(&inode->i_mutex);12951295 if (err) {12961296 dput(dentry);12971297 dentry = NULL;
+3-3
fs/reiserfs/xattr_acl.c
···174174/*175175 * Inode operation get_posix_acl().176176 *177177- * inode->i_sem: down177177+ * inode->i_mutex: down178178 * BKL held [before 2.5.x]179179 */180180struct posix_acl *reiserfs_get_acl(struct inode *inode, int type)···237237/*238238 * Inode operation set_posix_acl().239239 *240240- * inode->i_sem: down240240+ * inode->i_mutex: down241241 * BKL held [before 2.5.x]242242 */243243static int···312312 return error;313313}314314315315-/* dir->i_sem: down,315315+/* dir->i_mutex: locked,316316 * inode is new and not released into the wild yet */317317int318318reiserfs_inherit_default_acl(struct inode *dir, struct dentry *dentry,
+6-6
fs/relayfs/inode.c
···109109 }110110111111 parent = dget(parent);112112- down(&parent->d_inode->i_sem);112112+ mutex_lock(&parent->d_inode->i_mutex);113113 d = lookup_one_len(name, parent, strlen(name));114114 if (IS_ERR(d)) {115115 d = NULL;···139139 simple_release_fs(&relayfs_mount, &relayfs_mount_count);140140141141exit:142142- up(&parent->d_inode->i_sem);142142+ mutex_unlock(&parent->d_inode->i_mutex);143143 dput(parent);144144 return d;145145}···204204 return -EINVAL;205205206206 parent = dget(parent);207207- down(&parent->d_inode->i_sem);207207+ mutex_lock(&parent->d_inode->i_mutex);208208 if (dentry->d_inode) {209209 if (S_ISDIR(dentry->d_inode->i_mode))210210 error = simple_rmdir(parent->d_inode, dentry);···215215 }216216 if (!error)217217 dput(dentry);218218- up(&parent->d_inode->i_sem);218218+ mutex_unlock(&parent->d_inode->i_mutex);219219 dput(parent);220220221221 if (!error)···476476 ssize_t ret = 0;477477 void *from;478478479479- down(&inode->i_sem);479479+ mutex_lock(&inode->i_mutex);480480 if(!relay_file_read_avail(buf, *ppos))481481 goto out;482482···494494 relay_file_read_consume(buf, read_start, count);495495 *ppos = relay_file_read_end_pos(buf, read_start, count);496496out:497497- up(&inode->i_sem);497497+ mutex_unlock(&inode->i_mutex);498498 return ret;499499}500500
···364364 umode_t mode = (attr->mode & S_IALLUGO) | S_IFREG;365365 int error = 0;366366367367- down(&dir->d_inode->i_sem);367367+ mutex_lock(&dir->d_inode->i_mutex);368368 error = sysfs_make_dirent(parent_sd, NULL, (void *) attr, mode, type);369369- up(&dir->d_inode->i_sem);369369+ mutex_unlock(&dir->d_inode->i_mutex);370370371371 return error;372372}···398398 struct dentry * victim;399399 int res = -ENOENT;400400401401- down(&dir->d_inode->i_sem);401401+ mutex_lock(&dir->d_inode->i_mutex);402402 victim = lookup_one_len(attr->name, dir, strlen(attr->name));403403 if (!IS_ERR(victim)) {404404 /* make sure dentry is really there */···420420 */421421 dput(victim);422422 }423423- up(&dir->d_inode->i_sem);423423+ mutex_unlock(&dir->d_inode->i_mutex);424424425425 return res;426426}···441441 struct iattr newattrs;442442 int res = -ENOENT;443443444444- down(&dir->d_inode->i_sem);444444+ mutex_lock(&dir->d_inode->i_mutex);445445 victim = lookup_one_len(attr->name, dir, strlen(attr->name));446446 if (!IS_ERR(victim)) {447447 if (victim->d_inode &&448448 (victim->d_parent->d_inode == dir->d_inode)) {449449 inode = victim->d_inode;450450- down(&inode->i_sem);450450+ mutex_lock(&inode->i_mutex);451451 newattrs.ia_mode = (mode & S_IALLUGO) |452452 (inode->i_mode & ~S_IALLUGO);453453 newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;454454 res = notify_change(victim, &newattrs);455455- up(&inode->i_sem);455455+ mutex_unlock(&inode->i_mutex);456456 }457457 dput(victim);458458 }459459- up(&dir->d_inode->i_sem);459459+ mutex_unlock(&dir->d_inode->i_mutex);460460461461 return res;462462}···480480EXPORT_SYMBOL_GPL(sysfs_create_file);481481EXPORT_SYMBOL_GPL(sysfs_remove_file);482482EXPORT_SYMBOL_GPL(sysfs_update_file);483483-
+3-5
fs/sysfs/inode.c
···201201202202/*203203 * Unhashes the dentry corresponding to given sysfs_dirent204204- * Called with parent inode's i_sem held.204204+ * Called with parent inode's i_mutex held.205205 */206206void sysfs_drop_dentry(struct sysfs_dirent * sd, struct dentry * parent)207207{···232232 /* no inode means this hasn't been made visible yet */233233 return;234234235235- down(&dir->d_inode->i_sem);235235+ mutex_lock(&dir->d_inode->i_mutex);236236 list_for_each_entry(sd, &parent_sd->s_children, s_sibling) {237237 if (!sd->s_element)238238 continue;···243243 break;244244 }245245 }246246- up(&dir->d_inode->i_sem);246246+ mutex_unlock(&dir->d_inode->i_mutex);247247}248248-249249-
···203203 ip->i_nlink = va.va_nlink;204204 ip->i_blocks = va.va_nblocks;205205206206- /* we're under i_sem so i_size can't change under us */206206+ /* we're under i_mutex so i_size can't change under us */207207 if (i_size_read(ip) != va.va_size)208208 i_size_write(ip, va.va_size);209209 }
+9-9
fs/xfs/linux-2.6/xfs_lrw.c
···254254 }255255256256 if (unlikely(ioflags & IO_ISDIRECT))257257- down(&inode->i_sem);257257+ mutex_lock(&inode->i_mutex);258258 xfs_ilock(ip, XFS_IOLOCK_SHARED);259259260260 if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_READ) &&···286286287287unlock_isem:288288 if (unlikely(ioflags & IO_ISDIRECT))289289- up(&inode->i_sem);289289+ mutex_unlock(&inode->i_mutex);290290 return ret;291291}292292···655655 iolock = XFS_IOLOCK_EXCL;656656 locktype = VRWLOCK_WRITE;657657658658- down(&inode->i_sem);658658+ mutex_lock(&inode->i_mutex);659659 } else {660660 iolock = XFS_IOLOCK_SHARED;661661 locktype = VRWLOCK_WRITE_DIRECT;···686686 int dmflags = FILP_DELAY_FLAG(file);687687688688 if (need_isem)689689- dmflags |= DM_FLAGS_ISEM;689689+ dmflags |= DM_FLAGS_IMUX;690690691691 xfs_iunlock(xip, XFS_ILOCK_EXCL);692692 error = XFS_SEND_DATA(xip->i_mount, DM_EVENT_WRITE, vp,···772772 if (need_isem) {773773 /* demote the lock now the cached pages are gone */774774 XFS_ILOCK_DEMOTE(mp, io, XFS_IOLOCK_EXCL);775775- up(&inode->i_sem);775775+ mutex_unlock(&inode->i_mutex);776776777777 iolock = XFS_IOLOCK_SHARED;778778 locktype = VRWLOCK_WRITE_DIRECT;···817817818818 xfs_rwunlock(bdp, locktype);819819 if (need_isem)820820- up(&inode->i_sem);820820+ mutex_unlock(&inode->i_mutex);821821 error = XFS_SEND_NAMESP(xip->i_mount, DM_EVENT_NOSPACE, vp,822822 DM_RIGHT_NULL, vp, DM_RIGHT_NULL, NULL, NULL,823823 0, 0, 0); /* Delay flag intentionally unused */824824 if (error)825825 goto out_nounlocks;826826 if (need_isem)827827- down(&inode->i_sem);827827+ mutex_lock(&inode->i_mutex);828828 xfs_rwlock(bdp, locktype);829829 pos = xip->i_d.di_size;830830 ret = 0;···926926927927 xfs_rwunlock(bdp, locktype);928928 if (need_isem)929929- up(&inode->i_sem);929929+ mutex_unlock(&inode->i_mutex);930930931931 error = sync_page_range(inode, mapping, pos, ret);932932 if (!error)···938938 xfs_rwunlock(bdp, locktype);939939 out_unlock_isem:940940 if (need_isem)941941- up(&inode->i_sem);941941+ mutex_unlock(&inode->i_mutex);942942 out_nounlocks:943943 return -error;944944}
···233233 */234234 ASSERT(mp->m_quotainfo);235235 if (mp->m_quotainfo)236236- mutex_lock(&(XFS_QI_QOFFLOCK(mp)), PINOD);236236+ mutex_lock(&(XFS_QI_QOFFLOCK(mp)));237237238238 ASSERT(mp->m_quotainfo);239239···508508 /*509509 * Switch on quota enforcement in core.510510 */511511- mutex_lock(&(XFS_QI_QOFFLOCK(mp)), PINOD);511511+ mutex_lock(&(XFS_QI_QOFFLOCK(mp)));512512 mp->m_qflags |= (flags & XFS_ALL_QUOTA_ENFD);513513 mutex_unlock(&(XFS_QI_QOFFLOCK(mp)));514514···617617 * a quotaoff from happening). (XXXThis doesn't currently happen618618 * because we take the vfslock before calling xfs_qm_sysent).619619 */620620- mutex_lock(&(XFS_QI_QOFFLOCK(mp)), PINOD);620620+ mutex_lock(&(XFS_QI_QOFFLOCK(mp)));621621622622 /*623623 * Get the dquot (locked), and join it to the transaction.···14261426 xfs_log_force(mp, (xfs_lsn_t)0, XFS_LOG_FORCE | XFS_LOG_SYNC);14271427 XFS_bflush(mp->m_ddev_targp);1428142814291429- mutex_lock(&qcheck_lock, PINOD);14291429+ mutex_lock(&qcheck_lock);14301430 /* There should be absolutely no quota activity while this14311431 is going on. */14321432 qmtest_udqtab = kmem_zalloc(qmtest_hashmask *
···2424void2525uuid_init(void)2626{2727- mutex_init(&uuid_monitor, MUTEX_DEFAULT, "uuid_monitor");2727+ mutex_init(&uuid_monitor);2828}29293030/*···9494{9595 int i, hole;96969797- mutex_lock(&uuid_monitor, PVFS);9797+ mutex_lock(&uuid_monitor);9898 for (i = 0, hole = -1; i < uuid_table_size; i++) {9999 if (uuid_is_nil(&uuid_table[i])) {100100 hole = i;···122122{123123 int i;124124125125- mutex_lock(&uuid_monitor, PVFS);125125+ mutex_lock(&uuid_monitor);126126 for (i = 0; i < uuid_table_size; i++) {127127 if (uuid_is_nil(&uuid_table[i]))128128 continue;
···533533 int msb_delta; /* Change to make to specified field */534534} xfs_mod_sb_t;535535536536-#define XFS_MOUNT_ILOCK(mp) mutex_lock(&((mp)->m_ilock), PINOD)536536+#define XFS_MOUNT_ILOCK(mp) mutex_lock(&((mp)->m_ilock))537537#define XFS_MOUNT_IUNLOCK(mp) mutex_unlock(&((mp)->m_ilock))538538#define XFS_SB_LOCK(mp) mutex_spinlock(&(mp)->m_sb_lock)539539#define XFS_SB_UNLOCK(mp,s) mutex_spinunlock(&(mp)->m_sb_lock,(s))
+1
include/asm-alpha/atomic.h
···176176}177177178178#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))179179+#define atomic_xchg(v, new) (xchg(&((v)->counter), new))179180180181#define atomic_add_unless(v, a, u) \181182({ \
+9
include/asm-alpha/mutex.h
···11+/*22+ * Pull in the generic implementation for the mutex fastpath.33+ *44+ * TODO: implement optimized primitives instead, or leave the generic55+ * implementation in place, or pick the atomic_xchg() based generic66+ * implementation. (see asm-generic/mutex-xchg.h for details)77+ */88+99+#include <asm-generic/mutex-dec.h>
+2
include/asm-arm/atomic.h
···175175176176#endif /* __LINUX_ARM_ARCH__ */177177178178+#define atomic_xchg(v, new) (xchg(&((v)->counter), new))179179+178180static inline int atomic_add_unless(atomic_t *v, int a, int u)179181{180182 int c, old;
+128
include/asm-arm/mutex.h
···11+/*22+ * include/asm-arm/mutex.h33+ *44+ * ARM optimized mutex locking primitives55+ *66+ * Please look into asm-generic/mutex-xchg.h for a formal definition.77+ */88+#ifndef _ASM_MUTEX_H99+#define _ASM_MUTEX_H1010+1111+#if __LINUX_ARM_ARCH__ < 61212+/* On pre-ARMv6 hardware the swp based implementation is the most efficient. */1313+# include <asm-generic/mutex-xchg.h>1414+#else1515+1616+/*1717+ * Attempting to lock a mutex on ARMv6+ can be done with a bastardized1818+ * atomic decrement (it is not a reliable atomic decrement but it satisfies1919+ * the defined semantics for our purpose, while being smaller and faster2020+ * than a real atomic decrement or atomic swap. The idea is to attempt2121+ * decrementing the lock value only once. If once decremented it isn't zero,2222+ * or if its store-back fails due to a dispute on the exclusive store, we2323+ * simply bail out immediately through the slow path where the lock will be2424+ * reattempted until it succeeds.2525+ */2626+#define __mutex_fastpath_lock(count, fail_fn) \2727+do { \2828+ int __ex_flag, __res; \2929+ \3030+ typecheck(atomic_t *, count); \3131+ typecheck_fn(fastcall void (*)(atomic_t *), fail_fn); \3232+ \3333+ __asm__ ( \3434+ "ldrex %0, [%2] \n" \3535+ "sub %0, %0, #1 \n" \3636+ "strex %1, %0, [%2] \n" \3737+ \3838+ : "=&r" (__res), "=&r" (__ex_flag) \3939+ : "r" (&(count)->counter) \4040+ : "cc","memory" ); \4141+ \4242+ if (unlikely(__res || __ex_flag)) \4343+ fail_fn(count); \4444+} while (0)4545+4646+#define __mutex_fastpath_lock_retval(count, fail_fn) \4747+({ \4848+ int __ex_flag, __res; \4949+ \5050+ typecheck(atomic_t *, count); \5151+ typecheck_fn(fastcall int (*)(atomic_t *), fail_fn); \5252+ \5353+ __asm__ ( \5454+ "ldrex %0, [%2] \n" \5555+ "sub %0, %0, #1 \n" \5656+ "strex %1, %0, [%2] \n" \5757+ \5858+ : "=&r" (__res), "=&r" (__ex_flag) \5959+ : "r" (&(count)->counter) \6060+ : "cc","memory" ); \6161+ \6262+ __res |= __ex_flag; \6363+ if (unlikely(__res != 0)) \6464+ __res = fail_fn(count); \6565+ __res; \6666+})6767+6868+/*6969+ * Same trick is used for the unlock fast path. However the original value,7070+ * rather than the result, is used to test for success in order to have7171+ * better generated assembly.7272+ */7373+#define __mutex_fastpath_unlock(count, fail_fn) \7474+do { \7575+ int __ex_flag, __res, __orig; \7676+ \7777+ typecheck(atomic_t *, count); \7878+ typecheck_fn(fastcall void (*)(atomic_t *), fail_fn); \7979+ \8080+ __asm__ ( \8181+ "ldrex %0, [%3] \n" \8282+ "add %1, %0, #1 \n" \8383+ "strex %2, %1, [%3] \n" \8484+ \8585+ : "=&r" (__orig), "=&r" (__res), "=&r" (__ex_flag) \8686+ : "r" (&(count)->counter) \8787+ : "cc","memory" ); \8888+ \8989+ if (unlikely(__orig || __ex_flag)) \9090+ fail_fn(count); \9191+} while (0)9292+9393+/*9494+ * If the unlock was done on a contended lock, or if the unlock simply fails9595+ * then the mutex remains locked.9696+ */9797+#define __mutex_slowpath_needs_to_unlock() 19898+9999+/*100100+ * For __mutex_fastpath_trylock we use another construct which could be101101+ * described as a "single value cmpxchg".102102+ *103103+ * This provides the needed trylock semantics like cmpxchg would, but it is104104+ * lighter and less generic than a true cmpxchg implementation.105105+ */106106+static inline int107107+__mutex_fastpath_trylock(atomic_t *count, int (*fail_fn)(atomic_t *))108108+{109109+ int __ex_flag, __res, __orig;110110+111111+ __asm__ (112112+113113+ "1: ldrex %0, [%3] \n"114114+ "subs %1, %0, #1 \n"115115+ "strexeq %2, %1, [%3] \n"116116+ "movlt %0, #0 \n"117117+ "cmpeq %2, #0 \n"118118+ "bgt 1b \n"119119+120120+ : "=&r" (__orig), "=&r" (__res), "=&r" (__ex_flag)121121+ : "r" (&count->counter)122122+ : "cc", "memory" );123123+124124+ return __orig;125125+}126126+127127+#endif128128+#endif
+2
include/asm-arm26/atomic.h
···7676 return ret;7777}78787979+#define atomic_xchg(v, new) (xchg(&((v)->counter), new))8080+7981static inline int atomic_add_unless(atomic_t *v, int a, int u)8082{8183 int ret;
+2
include/asm-cris/atomic.h
···136136 return ret;137137}138138139139+#define atomic_xchg(v, new) (xchg(&((v)->counter), new))140140+139141static inline int atomic_add_unless(atomic_t *v, int a, int u)140142{141143 int ret;
+9
include/asm-cris/mutex.h
···11+/*22+ * Pull in the generic implementation for the mutex fastpath.33+ *44+ * TODO: implement optimized primitives instead, or leave the generic55+ * implementation in place, or pick the atomic_xchg() based generic66+ * implementation. (see asm-generic/mutex-xchg.h for details)77+ */88+99+#include <asm-generic/mutex-dec.h>
···11+/*22+ * Pull in the generic implementation for the mutex fastpath.33+ *44+ * TODO: implement optimized primitives instead, or leave the generic55+ * implementation in place, or pick the atomic_xchg() based generic66+ * implementation. (see asm-generic/mutex-xchg.h for details)77+ */88+99+#include <asm-generic/mutex-dec.h>
+110
include/asm-generic/mutex-dec.h
···11+/*22+ * asm-generic/mutex-dec.h33+ *44+ * Generic implementation of the mutex fastpath, based on atomic55+ * decrement/increment.66+ */77+#ifndef _ASM_GENERIC_MUTEX_DEC_H88+#define _ASM_GENERIC_MUTEX_DEC_H99+1010+/**1111+ * __mutex_fastpath_lock - try to take the lock by moving the count1212+ * from 1 to a 0 value1313+ * @count: pointer of type atomic_t1414+ * @fail_fn: function to call if the original value was not 11515+ *1616+ * Change the count from 1 to a value lower than 1, and call <fail_fn> if1717+ * it wasn't 1 originally. This function MUST leave the value lower than1818+ * 1 even when the "1" assertion wasn't true.1919+ */2020+#define __mutex_fastpath_lock(count, fail_fn) \2121+do { \2222+ if (unlikely(atomic_dec_return(count) < 0)) \2323+ fail_fn(count); \2424+ else \2525+ smp_mb(); \2626+} while (0)2727+2828+/**2929+ * __mutex_fastpath_lock_retval - try to take the lock by moving the count3030+ * from 1 to a 0 value3131+ * @count: pointer of type atomic_t3232+ * @fail_fn: function to call if the original value was not 13333+ *3434+ * Change the count from 1 to a value lower than 1, and call <fail_fn> if3535+ * it wasn't 1 originally. This function returns 0 if the fastpath succeeds,3636+ * or anything the slow path function returns.3737+ */3838+static inline int3939+__mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *))4040+{4141+ if (unlikely(atomic_dec_return(count) < 0))4242+ return fail_fn(count);4343+ else {4444+ smp_mb();4545+ return 0;4646+ }4747+}4848+4949+/**5050+ * __mutex_fastpath_unlock - try to promote the count from 0 to 15151+ * @count: pointer of type atomic_t5252+ * @fail_fn: function to call if the original value was not 05353+ *5454+ * Try to promote the count from 0 to 1. If it wasn't 0, call <fail_fn>.5555+ * In the failure case, this function is allowed to either set the value to5656+ * 1, or to set it to a value lower than 1.5757+ *5858+ * If the implementation sets it to a value of lower than 1, then the5959+ * __mutex_slowpath_needs_to_unlock() macro needs to return 1, it needs6060+ * to return 0 otherwise.6161+ */6262+#define __mutex_fastpath_unlock(count, fail_fn) \6363+do { \6464+ smp_mb(); \6565+ if (unlikely(atomic_inc_return(count) <= 0)) \6666+ fail_fn(count); \6767+} while (0)6868+6969+#define __mutex_slowpath_needs_to_unlock() 17070+7171+/**7272+ * __mutex_fastpath_trylock - try to acquire the mutex, without waiting7373+ *7474+ * @count: pointer of type atomic_t7575+ * @fail_fn: fallback function7676+ *7777+ * Change the count from 1 to a value lower than 1, and return 0 (failure)7878+ * if it wasn't 1 originally, or return 1 (success) otherwise. This function7979+ * MUST leave the value lower than 1 even when the "1" assertion wasn't true.8080+ * Additionally, if the value was < 0 originally, this function must not leave8181+ * it to 0 on failure.8282+ *8383+ * If the architecture has no effective trylock variant, it should call the8484+ * <fail_fn> spinlock-based trylock variant unconditionally.8585+ */8686+static inline int8787+__mutex_fastpath_trylock(atomic_t *count, int (*fail_fn)(atomic_t *))8888+{8989+ /*9090+ * We have two variants here. The cmpxchg based one is the best one9191+ * because it never induce a false contention state. It is included9292+ * here because architectures using the inc/dec algorithms over the9393+ * xchg ones are much more likely to support cmpxchg natively.9494+ *9595+ * If not we fall back to the spinlock based variant - that is9696+ * just as efficient (and simpler) as a 'destructive' probing of9797+ * the mutex state would be.9898+ */9999+#ifdef __HAVE_ARCH_CMPXCHG100100+ if (likely(atomic_cmpxchg(count, 1, 0)) == 1) {101101+ smp_mb();102102+ return 1;103103+ }104104+ return 0;105105+#else106106+ return fail_fn(count);107107+#endif108108+}109109+110110+#endif
+24
include/asm-generic/mutex-null.h
···11+/*22+ * asm-generic/mutex-null.h33+ *44+ * Generic implementation of the mutex fastpath, based on NOP :-)55+ *66+ * This is used by the mutex-debugging infrastructure, but it can also77+ * be used by architectures that (for whatever reason) want to use the88+ * spinlock based slowpath.99+ */1010+#ifndef _ASM_GENERIC_MUTEX_NULL_H1111+#define _ASM_GENERIC_MUTEX_NULL_H1212+1313+/* extra parameter only needed for mutex debugging: */1414+#ifndef __IP__1515+# define __IP__1616+#endif1717+1818+#define __mutex_fastpath_lock(count, fail_fn) fail_fn(count __RET_IP__)1919+#define __mutex_fastpath_lock_retval(count, fail_fn) fail_fn(count __RET_IP__)2020+#define __mutex_fastpath_unlock(count, fail_fn) fail_fn(count __RET_IP__)2121+#define __mutex_fastpath_trylock(count, fail_fn) fail_fn(count)2222+#define __mutex_slowpath_needs_to_unlock() 12323+2424+#endif
+117
include/asm-generic/mutex-xchg.h
···11+/*22+ * asm-generic/mutex-xchg.h33+ *44+ * Generic implementation of the mutex fastpath, based on xchg().55+ *66+ * NOTE: An xchg based implementation is less optimal than an atomic77+ * decrement/increment based implementation. If your architecture88+ * has a reasonable atomic dec/inc then you should probably use99+ * asm-generic/mutex-dec.h instead, or you could open-code an1010+ * optimized version in asm/mutex.h.1111+ */1212+#ifndef _ASM_GENERIC_MUTEX_XCHG_H1313+#define _ASM_GENERIC_MUTEX_XCHG_H1414+1515+/**1616+ * __mutex_fastpath_lock - try to take the lock by moving the count1717+ * from 1 to a 0 value1818+ * @count: pointer of type atomic_t1919+ * @fail_fn: function to call if the original value was not 12020+ *2121+ * Change the count from 1 to a value lower than 1, and call <fail_fn> if it2222+ * wasn't 1 originally. This function MUST leave the value lower than 12323+ * even when the "1" assertion wasn't true.2424+ */2525+#define __mutex_fastpath_lock(count, fail_fn) \2626+do { \2727+ if (unlikely(atomic_xchg(count, 0) != 1)) \2828+ fail_fn(count); \2929+ else \3030+ smp_mb(); \3131+} while (0)3232+3333+3434+/**3535+ * __mutex_fastpath_lock_retval - try to take the lock by moving the count3636+ * from 1 to a 0 value3737+ * @count: pointer of type atomic_t3838+ * @fail_fn: function to call if the original value was not 13939+ *4040+ * Change the count from 1 to a value lower than 1, and call <fail_fn> if it4141+ * wasn't 1 originally. This function returns 0 if the fastpath succeeds,4242+ * or anything the slow path function returns4343+ */4444+static inline int4545+__mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *))4646+{4747+ if (unlikely(atomic_xchg(count, 0) != 1))4848+ return fail_fn(count);4949+ else {5050+ smp_mb();5151+ return 0;5252+ }5353+}5454+5555+/**5656+ * __mutex_fastpath_unlock - try to promote the mutex from 0 to 15757+ * @count: pointer of type atomic_t5858+ * @fail_fn: function to call if the original value was not 05959+ *6060+ * try to promote the mutex from 0 to 1. if it wasn't 0, call <function>6161+ * In the failure case, this function is allowed to either set the value to6262+ * 1, or to set it to a value lower than one.6363+ * If the implementation sets it to a value of lower than one, the6464+ * __mutex_slowpath_needs_to_unlock() macro needs to return 1, it needs6565+ * to return 0 otherwise.6666+ */6767+#define __mutex_fastpath_unlock(count, fail_fn) \6868+do { \6969+ smp_mb(); \7070+ if (unlikely(atomic_xchg(count, 1) != 0)) \7171+ fail_fn(count); \7272+} while (0)7373+7474+#define __mutex_slowpath_needs_to_unlock() 07575+7676+/**7777+ * __mutex_fastpath_trylock - try to acquire the mutex, without waiting7878+ *7979+ * @count: pointer of type atomic_t8080+ * @fail_fn: spinlock based trylock implementation8181+ *8282+ * Change the count from 1 to a value lower than 1, and return 0 (failure)8383+ * if it wasn't 1 originally, or return 1 (success) otherwise. This function8484+ * MUST leave the value lower than 1 even when the "1" assertion wasn't true.8585+ * Additionally, if the value was < 0 originally, this function must not leave8686+ * it to 0 on failure.8787+ *8888+ * If the architecture has no effective trylock variant, it should call the8989+ * <fail_fn> spinlock-based trylock variant unconditionally.9090+ */9191+static inline int9292+__mutex_fastpath_trylock(atomic_t *count, int (*fail_fn)(atomic_t *))9393+{9494+ int prev = atomic_xchg(count, 0);9595+9696+ if (unlikely(prev < 0)) {9797+ /*9898+ * The lock was marked contended so we must restore that9999+ * state. If while doing so we get back a prev value of 1100100+ * then we just own it.101101+ *102102+ * [ In the rare case of the mutex going to 1, to 0, to -1103103+ * and then back to 0 in this few-instructions window,104104+ * this has the potential to trigger the slowpath for the105105+ * owner's unlock path needlessly, but that's not a problem106106+ * in practice. ]107107+ */108108+ prev = atomic_xchg(count, prev);109109+ if (prev < 0)110110+ prev = 0;111111+ }112112+ smp_mb();113113+114114+ return prev;115115+}116116+117117+#endif
+2
include/asm-h8300/atomic.h
···9595 return ret;9696}97979898+#define atomic_xchg(v, new) (xchg(&((v)->counter), new))9999+98100static inline int atomic_add_unless(atomic_t *v, int a, int u)99101{100102 int ret;
+9
include/asm-h8300/mutex.h
···11+/*22+ * Pull in the generic implementation for the mutex fastpath.33+ *44+ * TODO: implement optimized primitives instead, or leave the generic55+ * implementation in place, or pick the atomic_xchg() based generic66+ * implementation. (see asm-generic/mutex-xchg.h for details)77+ */88+99+#include <asm-generic/mutex-dec.h>
+1
include/asm-i386/atomic.h
···216216}217217218218#define atomic_cmpxchg(v, old, new) ((int)cmpxchg(&((v)->counter), old, new))219219+#define atomic_xchg(v, new) (xchg(&((v)->counter), new))219220220221/**221222 * atomic_add_unless - add unless the number is a given value
+124
include/asm-i386/mutex.h
···11+/*22+ * Assembly implementation of the mutex fastpath, based on atomic33+ * decrement/increment.44+ *55+ * started by Ingo Molnar:66+ *77+ * Copyright (C) 2004, 2005, 2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>88+ */99+#ifndef _ASM_MUTEX_H1010+#define _ASM_MUTEX_H1111+1212+/**1313+ * __mutex_fastpath_lock - try to take the lock by moving the count1414+ * from 1 to a 0 value1515+ * @count: pointer of type atomic_t1616+ * @fn: function to call if the original value was not 11717+ *1818+ * Change the count from 1 to a value lower than 1, and call <fn> if it1919+ * wasn't 1 originally. This function MUST leave the value lower than 12020+ * even when the "1" assertion wasn't true.2121+ */2222+#define __mutex_fastpath_lock(count, fail_fn) \2323+do { \2424+ unsigned int dummy; \2525+ \2626+ typecheck(atomic_t *, count); \2727+ typecheck_fn(fastcall void (*)(atomic_t *), fail_fn); \2828+ \2929+ __asm__ __volatile__( \3030+ LOCK " decl (%%eax) \n" \3131+ " js "#fail_fn" \n" \3232+ \3333+ :"=a" (dummy) \3434+ : "a" (count) \3535+ : "memory", "ecx", "edx"); \3636+} while (0)3737+3838+3939+/**4040+ * __mutex_fastpath_lock_retval - try to take the lock by moving the count4141+ * from 1 to a 0 value4242+ * @count: pointer of type atomic_t4343+ * @fail_fn: function to call if the original value was not 14444+ *4545+ * Change the count from 1 to a value lower than 1, and call <fail_fn> if it4646+ * wasn't 1 originally. This function returns 0 if the fastpath succeeds,4747+ * or anything the slow path function returns4848+ */4949+static inline int5050+__mutex_fastpath_lock_retval(atomic_t *count,5151+ int fastcall (*fail_fn)(atomic_t *))5252+{5353+ if (unlikely(atomic_dec_return(count) < 0))5454+ return fail_fn(count);5555+ else5656+ return 0;5757+}5858+5959+/**6060+ * __mutex_fastpath_unlock - try to promote the mutex from 0 to 16161+ * @count: pointer of type atomic_t6262+ * @fail_fn: function to call if the original value was not 06363+ *6464+ * try to promote the mutex from 0 to 1. if it wasn't 0, call <fail_fn>.6565+ * In the failure case, this function is allowed to either set the value6666+ * to 1, or to set it to a value lower than 1.6767+ *6868+ * If the implementation sets it to a value of lower than 1, the6969+ * __mutex_slowpath_needs_to_unlock() macro needs to return 1, it needs7070+ * to return 0 otherwise.7171+ */7272+#define __mutex_fastpath_unlock(count, fail_fn) \7373+do { \7474+ unsigned int dummy; \7575+ \7676+ typecheck(atomic_t *, count); \7777+ typecheck_fn(fastcall void (*)(atomic_t *), fail_fn); \7878+ \7979+ __asm__ __volatile__( \8080+ LOCK " incl (%%eax) \n" \8181+ " jle "#fail_fn" \n" \8282+ \8383+ :"=a" (dummy) \8484+ : "a" (count) \8585+ : "memory", "ecx", "edx"); \8686+} while (0)8787+8888+#define __mutex_slowpath_needs_to_unlock() 18989+9090+/**9191+ * __mutex_fastpath_trylock - try to acquire the mutex, without waiting9292+ *9393+ * @count: pointer of type atomic_t9494+ * @fail_fn: fallback function9595+ *9696+ * Change the count from 1 to a value lower than 1, and return 0 (failure)9797+ * if it wasn't 1 originally, or return 1 (success) otherwise. This function9898+ * MUST leave the value lower than 1 even when the "1" assertion wasn't true.9999+ * Additionally, if the value was < 0 originally, this function must not leave100100+ * it to 0 on failure.101101+ */102102+static inline int103103+__mutex_fastpath_trylock(atomic_t *count, int (*fail_fn)(atomic_t *))104104+{105105+ /*106106+ * We have two variants here. The cmpxchg based one is the best one107107+ * because it never induce a false contention state. It is included108108+ * here because architectures using the inc/dec algorithms over the109109+ * xchg ones are much more likely to support cmpxchg natively.110110+ *111111+ * If not we fall back to the spinlock based variant - that is112112+ * just as efficient (and simpler) as a 'destructive' probing of113113+ * the mutex state would be.114114+ */115115+#ifdef __HAVE_ARCH_CMPXCHG116116+ if (likely(atomic_cmpxchg(count, 1, 0)) == 1)117117+ return 1;118118+ return 0;119119+#else120120+ return fail_fn(count);121121+#endif122122+}123123+124124+#endif
···11+/*22+ * Pull in the generic implementation for the mutex fastpath.33+ *44+ * TODO: implement optimized primitives instead, or leave the generic55+ * implementation in place, or pick the atomic_xchg() based generic66+ * implementation. (see asm-generic/mutex-xchg.h for details)77+ */88+99+#include <asm-generic/mutex-dec.h>
+1
include/asm-m32r/atomic.h
···243243#define atomic_add_negative(i,v) (atomic_add_return((i), (v)) < 0)244244245245#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))246246+#define atomic_xchg(v, new) (xchg(&((v)->counter), new))246247247248/**248249 * atomic_add_unless - add unless the number is a given value
+9
include/asm-m32r/mutex.h
···11+/*22+ * Pull in the generic implementation for the mutex fastpath.33+ *44+ * TODO: implement optimized primitives instead, or leave the generic55+ * implementation in place, or pick the atomic_xchg() based generic66+ * implementation. (see asm-generic/mutex-xchg.h for details)77+ */88+99+#include <asm-generic/mutex-dec.h>
+1
include/asm-m68k/atomic.h
···140140}141141142142#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))143143+#define atomic_xchg(v, new) (xchg(&((v)->counter), new))143144144145#define atomic_add_unless(v, a, u) \145146({ \
+9
include/asm-m68k/mutex.h
···11+/*22+ * Pull in the generic implementation for the mutex fastpath.33+ *44+ * TODO: implement optimized primitives instead, or leave the generic55+ * implementation in place, or pick the atomic_xchg() based generic66+ * implementation. (see asm-generic/mutex-xchg.h for details)77+ */88+99+#include <asm-generic/mutex-dec.h>
+1
include/asm-m68knommu/atomic.h
···129129}130130131131#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))132132+#define atomic_xchg(v, new) (xchg(&((v)->counter), new))132133133134#define atomic_add_unless(v, a, u) \134135({ \
+9
include/asm-m68knommu/mutex.h
···11+/*22+ * Pull in the generic implementation for the mutex fastpath.33+ *44+ * TODO: implement optimized primitives instead, or leave the generic55+ * implementation in place, or pick the atomic_xchg() based generic66+ * implementation. (see asm-generic/mutex-xchg.h for details)77+ */88+99+#include <asm-generic/mutex-dec.h>
+1
include/asm-mips/atomic.h
···289289}290290291291#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))292292+#define atomic_xchg(v, new) (xchg(&((v)->counter), new))292293293294/**294295 * atomic_add_unless - add unless the number is a given value
+9
include/asm-mips/mutex.h
···11+/*22+ * Pull in the generic implementation for the mutex fastpath.33+ *44+ * TODO: implement optimized primitives instead, or leave the generic55+ * implementation in place, or pick the atomic_xchg() based generic66+ * implementation. (see asm-generic/mutex-xchg.h for details)77+ */88+99+#include <asm-generic/mutex-dec.h>
+1
include/asm-parisc/atomic.h
···165165166166/* exported interface */167167#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))168168+#define atomic_xchg(v, new) (xchg(&((v)->counter), new))168169169170/**170171 * atomic_add_unless - add unless the number is a given value
+9
include/asm-parisc/mutex.h
···11+/*22+ * Pull in the generic implementation for the mutex fastpath.33+ *44+ * TODO: implement optimized primitives instead, or leave the generic55+ * implementation in place, or pick the atomic_xchg() based generic66+ * implementation. (see asm-generic/mutex-xchg.h for details)77+ */88+99+#include <asm-generic/mutex-dec.h>
+1
include/asm-powerpc/atomic.h
···165165}166166167167#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))168168+#define atomic_xchg(v, new) (xchg(&((v)->counter), new))168169169170/**170171 * atomic_add_unless - add unless the number is a given value
+9
include/asm-powerpc/mutex.h
···11+/*22+ * Pull in the generic implementation for the mutex fastpath.33+ *44+ * TODO: implement optimized primitives instead, or leave the generic55+ * implementation in place, or pick the atomic_xchg() based generic66+ * implementation. (see asm-generic/mutex-xchg.h for details)77+ */88+99+#include <asm-generic/mutex-dec.h>
+2
include/asm-s390/atomic.h
···7575 __CS_LOOP(v, mask, "or");7676}77777878+#define atomic_xchg(v, new) (xchg(&((v)->counter), new))7979+7880static __inline__ int atomic_cmpxchg(atomic_t *v, int old, int new)7981{8082 __asm__ __volatile__(" cs %0,%3,0(%2)\n"
+9
include/asm-s390/mutex.h
···11+/*22+ * Pull in the generic implementation for the mutex fastpath.33+ *44+ * TODO: implement optimized primitives instead, or leave the generic55+ * implementation in place, or pick the atomic_xchg() based generic66+ * implementation. (see asm-generic/mutex-xchg.h for details)77+ */88+99+#include <asm-generic/mutex-dec.h>
+2
include/asm-sh/atomic.h
···101101 return ret;102102}103103104104+#define atomic_xchg(v, new) (xchg(&((v)->counter), new))105105+104106static inline int atomic_add_unless(atomic_t *v, int a, int u)105107{106108 int ret;
+9
include/asm-sh/mutex.h
···11+/*22+ * Pull in the generic implementation for the mutex fastpath.33+ *44+ * TODO: implement optimized primitives instead, or leave the generic55+ * implementation in place, or pick the atomic_xchg() based generic66+ * implementation. (see asm-generic/mutex-xchg.h for details)77+ */88+99+#include <asm-generic/mutex-dec.h>
+2
include/asm-sh64/atomic.h
···113113 return ret;114114}115115116116+#define atomic_xchg(v, new) (xchg(&((v)->counter), new))117117+116118static inline int atomic_add_unless(atomic_t *v, int a, int u)117119{118120 int ret;
+9
include/asm-sh64/mutex.h
···11+/*22+ * Pull in the generic implementation for the mutex fastpath.33+ *44+ * TODO: implement optimized primitives instead, or leave the generic55+ * implementation in place, or pick the atomic_xchg() based generic66+ * implementation. (see asm-generic/mutex-xchg.h for details)77+ */88+99+#include <asm-generic/mutex-dec.h>
+1
include/asm-sparc/atomic.h
···20202121extern int __atomic_add_return(int, atomic_t *);2222extern int atomic_cmpxchg(atomic_t *, int, int);2323+#define atomic_xchg(v, new) (xchg(&((v)->counter), new))2324extern int atomic_add_unless(atomic_t *, int, int);2425extern void atomic_set(atomic_t *, int);2526
+9
include/asm-sparc/mutex.h
···11+/*22+ * Pull in the generic implementation for the mutex fastpath.33+ *44+ * TODO: implement optimized primitives instead, or leave the generic55+ * implementation in place, or pick the atomic_xchg() based generic66+ * implementation. (see asm-generic/mutex-xchg.h for details)77+ */88+99+#include <asm-generic/mutex-dec.h>
···11+/*22+ * Pull in the generic implementation for the mutex fastpath.33+ *44+ * TODO: implement optimized primitives instead, or leave the generic55+ * implementation in place, or pick the atomic_xchg() based generic66+ * implementation. (see asm-generic/mutex-xchg.h for details)77+ */88+99+#include <asm-generic/mutex-dec.h>
+9
include/asm-um/mutex.h
···11+/*22+ * Pull in the generic implementation for the mutex fastpath.33+ *44+ * TODO: implement optimized primitives instead, or leave the generic55+ * implementation in place, or pick the atomic_xchg() based generic66+ * implementation. (see asm-generic/mutex-xchg.h for details)77+ */88+99+#include <asm-generic/mutex-dec.h>
+2
include/asm-v850/atomic.h
···104104 return ret;105105}106106107107+#define atomic_xchg(v, new) (xchg(&((v)->counter), new))108108+107109static inline int atomic_add_unless(atomic_t *v, int a, int u)108110{109111 int ret;
+9
include/asm-v850/mutex.h
···11+/*22+ * Pull in the generic implementation for the mutex fastpath.33+ *44+ * TODO: implement optimized primitives instead, or leave the generic55+ * implementation in place, or pick the atomic_xchg() based generic66+ * implementation. (see asm-generic/mutex-xchg.h for details)77+ */88+99+#include <asm-generic/mutex-dec.h>
+1
include/asm-x86_64/atomic.h
···389389#define atomic64_dec_return(v) (atomic64_sub_return(1,v))390390391391#define atomic_cmpxchg(v, old, new) ((int)cmpxchg(&((v)->counter), old, new))392392+#define atomic_xchg(v, new) (xchg(&((v)->counter), new))392393393394/**394395 * atomic_add_unless - add unless the number is a given value
+113
include/asm-x86_64/mutex.h
···11+/*22+ * Assembly implementation of the mutex fastpath, based on atomic33+ * decrement/increment.44+ *55+ * started by Ingo Molnar:66+ *77+ * Copyright (C) 2004, 2005, 2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>88+ */99+#ifndef _ASM_MUTEX_H1010+#define _ASM_MUTEX_H1111+1212+/**1313+ * __mutex_fastpath_lock - decrement and call function if negative1414+ * @v: pointer of type atomic_t1515+ * @fail_fn: function to call if the result is negative1616+ *1717+ * Atomically decrements @v and calls <fail_fn> if the result is negative.1818+ */1919+#define __mutex_fastpath_lock(v, fail_fn) \2020+do { \2121+ unsigned long dummy; \2222+ \2323+ typecheck(atomic_t *, v); \2424+ typecheck_fn(fastcall void (*)(atomic_t *), fail_fn); \2525+ \2626+ __asm__ __volatile__( \2727+ LOCK " decl (%%rdi) \n" \2828+ " js 2f \n" \2929+ "1: \n" \3030+ \3131+ LOCK_SECTION_START("") \3232+ "2: call "#fail_fn" \n" \3333+ " jmp 1b \n" \3434+ LOCK_SECTION_END \3535+ \3636+ :"=D" (dummy) \3737+ : "D" (v) \3838+ : "rax", "rsi", "rdx", "rcx", \3939+ "r8", "r9", "r10", "r11", "memory"); \4040+} while (0)4141+4242+/**4343+ * __mutex_fastpath_lock_retval - try to take the lock by moving the count4444+ * from 1 to a 0 value4545+ * @count: pointer of type atomic_t4646+ * @fail_fn: function to call if the original value was not 14747+ *4848+ * Change the count from 1 to a value lower than 1, and call <fail_fn> if4949+ * it wasn't 1 originally. This function returns 0 if the fastpath succeeds,5050+ * or anything the slow path function returns5151+ */5252+static inline int5353+__mutex_fastpath_lock_retval(atomic_t *count,5454+ int fastcall (*fail_fn)(atomic_t *))5555+{5656+ if (unlikely(atomic_dec_return(count) < 0))5757+ return fail_fn(count);5858+ else5959+ return 0;6060+}6161+6262+/**6363+ * __mutex_fastpath_unlock - increment and call function if nonpositive6464+ * @v: pointer of type atomic_t6565+ * @fail_fn: function to call if the result is nonpositive6666+ *6767+ * Atomically increments @v and calls <fail_fn> if the result is nonpositive.6868+ */6969+#define __mutex_fastpath_unlock(v, fail_fn) \7070+do { \7171+ unsigned long dummy; \7272+ \7373+ typecheck(atomic_t *, v); \7474+ typecheck_fn(fastcall void (*)(atomic_t *), fail_fn); \7575+ \7676+ __asm__ __volatile__( \7777+ LOCK " incl (%%rdi) \n" \7878+ " jle 2f \n" \7979+ "1: \n" \8080+ \8181+ LOCK_SECTION_START("") \8282+ "2: call "#fail_fn" \n" \8383+ " jmp 1b \n" \8484+ LOCK_SECTION_END \8585+ \8686+ :"=D" (dummy) \8787+ : "D" (v) \8888+ : "rax", "rsi", "rdx", "rcx", \8989+ "r8", "r9", "r10", "r11", "memory"); \9090+} while (0)9191+9292+#define __mutex_slowpath_needs_to_unlock() 19393+9494+/**9595+ * __mutex_fastpath_trylock - try to acquire the mutex, without waiting9696+ *9797+ * @count: pointer of type atomic_t9898+ * @fail_fn: fallback function9999+ *100100+ * Change the count from 1 to 0 and return 1 (success), or return 0 (failure)101101+ * if it wasn't 1 originally. [the fallback function is never used on102102+ * x86_64, because all x86_64 CPUs have a CMPXCHG instruction.]103103+ */104104+static inline int105105+__mutex_fastpath_trylock(atomic_t *count, int (*fail_fn)(atomic_t *))106106+{107107+ if (likely(atomic_cmpxchg(count, 1, 0)) == 1)108108+ return 1;109109+ else110110+ return 0;111111+}112112+113113+#endif
+1
include/asm-xtensa/atomic.h
···224224#define atomic_add_negative(i,v) (atomic_add_return((i),(v)) < 0)225225226226#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))227227+#define atomic_xchg(v, new) (xchg(&((v)->counter), new))227228228229/**229230 * atomic_add_unless - add unless the number is a given value
+9
include/asm-xtensa/mutex.h
···11+/*22+ * Pull in the generic implementation for the mutex fastpath.33+ *44+ * TODO: implement optimized primitives instead, or leave the generic55+ * implementation in place, or pick the atomic_xchg() based generic66+ * implementation. (see asm-generic/mutex-xchg.h for details)77+ */88+99+#include <asm-generic/mutex-dec.h>
+1-1
include/linux/ext3_fs_i.h
···8787#ifdef CONFIG_EXT3_FS_XATTR8888 /*8989 * Extended attributes can be read independently of the main file9090- * data. Taking i_sem even when reading would cause contention9090+ * data. Taking i_mutex even when reading would cause contention9191 * between readers of EAs and writers of regular file data, so9292 * instead we synchronize on xattr_sem when reading or changing9393 * EAs.
+7-6
include/linux/fs.h
···219219#include <linux/prio_tree.h>220220#include <linux/init.h>221221#include <linux/sched.h>222222+#include <linux/mutex.h>222223223224#include <asm/atomic.h>224225#include <asm/semaphore.h>···485484 unsigned long i_blocks;486485 unsigned short i_bytes;487486 spinlock_t i_lock; /* i_blocks, i_bytes, maybe i_size */488488- struct semaphore i_sem;487487+ struct mutex i_mutex;489488 struct rw_semaphore i_alloc_sem;490489 struct inode_operations *i_op;491490 struct file_operations *i_fop; /* former ->i_op->default_file_ops */···821820 unsigned long s_magic;822821 struct dentry *s_root;823822 struct rw_semaphore s_umount;824824- struct semaphore s_lock;823823+ struct mutex s_lock;825824 int s_count;826825 int s_syncing;827826 int s_need_sync_fs;···893892static inline void lock_super(struct super_block * sb)894893{895894 get_fs_excl();896896- down(&sb->s_lock);895895+ mutex_lock(&sb->s_lock);897896}898897899898static inline void unlock_super(struct super_block * sb)900899{901900 put_fs_excl();902902- up(&sb->s_lock);901901+ mutex_unlock(&sb->s_lock);903902}904903905904/*···11921191 * directory. The name should be stored in the @name (with the11931192 * understanding that it is already pointing to a a %NAME_MAX+1 sized11941193 * buffer. get_name() should return %0 on success, a negative error code11951195- * or error. @get_name will be called without @parent->i_sem held.11941194+ * or error. @get_name will be called without @parent->i_mutex held.11961195 *11971196 * get_parent:11981197 * @get_parent should find the parent directory for the given @child which···12141213 * nfsd_find_fh_dentry() in either the @obj or @parent parameters.12151214 *12161215 * Locking rules:12171217- * get_parent is called with child->d_inode->i_sem down12161216+ * get_parent is called with child->d_inode->i_mutex down12181217 * get_name is not (which is possibly inconsistent)12191218 */12201219
+3-2
include/linux/ide.h
···1818#include <linux/bio.h>1919#include <linux/device.h>2020#include <linux/pci.h>2121+#include <linux/completion.h>2122#include <asm/byteorder.h>2223#include <asm/system.h>2324#include <asm/io.h>···639638 int crc_count; /* crc counter to reduce drive speed */640639 struct list_head list;641640 struct device gendev;642642- struct semaphore gendev_rel_sem; /* to deal with device release() */641641+ struct completion gendev_rel_comp; /* to deal with device release() */643642} ide_drive_t;644643645644#define to_ide_device(dev)container_of(dev, ide_drive_t, gendev)···795794 unsigned sg_mapped : 1; /* sg_table and sg_nents are ready */796795797796 struct device gendev;798798- struct semaphore gendev_rel_sem; /* To deal with device release() */797797+ struct completion gendev_rel_comp; /* To deal with device release() */799798800799 void *hwif_data; /* extra hwif data */801800
+2-2
include/linux/jffs2_fs_i.h
···88#include <asm/semaphore.h>991010struct jffs2_inode_info {1111- /* We need an internal semaphore similar to inode->i_sem.1111+ /* We need an internal mutex similar to inode->i_mutex.1212 Unfortunately, we can't used the existing one, because1313 either the GC would deadlock, or we'd have to release it1414 before letting GC proceed. Or we'd have to put ugliness1515- into the GC code so it didn't attempt to obtain the i_sem1515+ into the GC code so it didn't attempt to obtain the i_mutex1616 for the inode(s) which are already locked */1717 struct semaphore sem;1818
+9
include/linux/kernel.h
···286286 1; \287287})288288289289+/*290290+ * Check at compile time that 'function' is a certain type, or is a pointer291291+ * to that type (needs to use typedef for the function type.)292292+ */293293+#define typecheck_fn(type,function) \294294+({ typeof(type) __tmp = function; \295295+ (void)__tmp; \296296+})297297+289298#endif /* __KERNEL__ */290299291300#define SI_LOAD_SHIFT 16
+2-2
include/linux/loop.h
···5858 struct bio *lo_bio;5959 struct bio *lo_biotail;6060 int lo_state;6161- struct semaphore lo_sem;6161+ struct completion lo_done;6262+ struct completion lo_bh_done;6263 struct semaphore lo_ctl_mutex;6363- struct semaphore lo_bh_mutex;6464 int lo_pending;65656666 request_queue_t *lo_queue;
+4
include/linux/mm.h
···1313#include <linux/rbtree.h>1414#include <linux/prio_tree.h>1515#include <linux/fs.h>1616+#include <linux/mutex.h>16171718struct mempolicy;1819struct anon_vma;···10251024static inline void10261025kernel_map_pages(struct page *page, int numpages, int enable)10271026{10271027+ if (!PageHighMem(page) && !enable)10281028+ mutex_debug_check_no_locks_freed(page_address(page),10291029+ page_address(page + numpages));10281030}10291031#endif10301032
···11+/*22+ * Mutexes: blocking mutual exclusion locks33+ *44+ * started by Ingo Molnar:55+ *66+ * Copyright (C) 2004, 2005, 2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>77+ *88+ * This file contains the main data structure and API definitions.99+ */1010+#ifndef __LINUX_MUTEX_H1111+#define __LINUX_MUTEX_H1212+1313+#include <linux/list.h>1414+#include <linux/spinlock_types.h>1515+1616+#include <asm/atomic.h>1717+1818+/*1919+ * Simple, straightforward mutexes with strict semantics:2020+ *2121+ * - only one task can hold the mutex at a time2222+ * - only the owner can unlock the mutex2323+ * - multiple unlocks are not permitted2424+ * - recursive locking is not permitted2525+ * - a mutex object must be initialized via the API2626+ * - a mutex object must not be initialized via memset or copying2727+ * - task may not exit with mutex held2828+ * - memory areas where held locks reside must not be freed2929+ * - held mutexes must not be reinitialized3030+ * - mutexes may not be used in irq contexts3131+ *3232+ * These semantics are fully enforced when DEBUG_MUTEXES is3333+ * enabled. Furthermore, besides enforcing the above rules, the mutex3434+ * debugging code also implements a number of additional features3535+ * that make lock debugging easier and faster:3636+ *3737+ * - uses symbolic names of mutexes, whenever they are printed in debug output3838+ * - point-of-acquire tracking, symbolic lookup of function names3939+ * - list of all locks held in the system, printout of them4040+ * - owner tracking4141+ * - detects self-recursing locks and prints out all relevant info4242+ * - detects multi-task circular deadlocks and prints out all affected4343+ * locks and tasks (and only those tasks)4444+ */4545+struct mutex {4646+ /* 1: unlocked, 0: locked, negative: locked, possible waiters */4747+ atomic_t count;4848+ spinlock_t wait_lock;4949+ struct list_head wait_list;5050+#ifdef CONFIG_DEBUG_MUTEXES5151+ struct thread_info *owner;5252+ struct list_head held_list;5353+ unsigned long acquire_ip;5454+ const char *name;5555+ void *magic;5656+#endif5757+};5858+5959+/*6060+ * This is the control structure for tasks blocked on mutex,6161+ * which resides on the blocked task's kernel stack:6262+ */6363+struct mutex_waiter {6464+ struct list_head list;6565+ struct task_struct *task;6666+#ifdef CONFIG_DEBUG_MUTEXES6767+ struct mutex *lock;6868+ void *magic;6969+#endif7070+};7171+7272+#ifdef CONFIG_DEBUG_MUTEXES7373+# include <linux/mutex-debug.h>7474+#else7575+# define __DEBUG_MUTEX_INITIALIZER(lockname)7676+# define mutex_init(mutex) __mutex_init(mutex, NULL)7777+# define mutex_destroy(mutex) do { } while (0)7878+# define mutex_debug_show_all_locks() do { } while (0)7979+# define mutex_debug_show_held_locks(p) do { } while (0)8080+# define mutex_debug_check_no_locks_held(task) do { } while (0)8181+# define mutex_debug_check_no_locks_freed(from, to) do { } while (0)8282+#endif8383+8484+#define __MUTEX_INITIALIZER(lockname) \8585+ { .count = ATOMIC_INIT(1) \8686+ , .wait_lock = SPIN_LOCK_UNLOCKED \8787+ , .wait_list = LIST_HEAD_INIT(lockname.wait_list) \8888+ __DEBUG_MUTEX_INITIALIZER(lockname) }8989+9090+#define DEFINE_MUTEX(mutexname) \9191+ struct mutex mutexname = __MUTEX_INITIALIZER(mutexname)9292+9393+extern void fastcall __mutex_init(struct mutex *lock, const char *name);9494+9595+/***9696+ * mutex_is_locked - is the mutex locked9797+ * @lock: the mutex to be queried9898+ *9999+ * Returns 1 if the mutex is locked, 0 if unlocked.100100+ */101101+static inline int fastcall mutex_is_locked(struct mutex *lock)102102+{103103+ return atomic_read(&lock->count) != 1;104104+}105105+106106+/*107107+ * See kernel/mutex.c for detailed documentation of these APIs.108108+ * Also see Documentation/mutex-design.txt.109109+ */110110+extern void fastcall mutex_lock(struct mutex *lock);111111+extern int fastcall mutex_lock_interruptible(struct mutex *lock);112112+/*113113+ * NOTE: mutex_trylock() follows the spin_trylock() convention,114114+ * not the down_trylock() convention!115115+ */116116+extern int fastcall mutex_trylock(struct mutex *lock);117117+extern void fastcall mutex_unlock(struct mutex *lock);118118+119119+#endif
+3-3
include/linux/nfsd/nfsfh.h
···294294/*295295 * Lock a file handle/inode296296 * NOTE: both fh_lock and fh_unlock are done "by hand" in297297- * vfs.c:nfsd_rename as it needs to grab 2 i_sem's at once297297+ * vfs.c:nfsd_rename as it needs to grab 2 i_mutex's at once298298 * so, any changes here should be reflected there.299299 */300300static inline void···317317 }318318319319 inode = dentry->d_inode;320320- down(&inode->i_sem);320320+ mutex_lock(&inode->i_mutex);321321 fill_pre_wcc(fhp);322322 fhp->fh_locked = 1;323323}···333333334334 if (fhp->fh_locked) {335335 fill_post_wcc(fhp);336336- up(&fhp->fh_dentry->d_inode->i_sem);336336+ mutex_unlock(&fhp->fh_dentry->d_inode->i_mutex);337337 fhp->fh_locked = 0;338338 }339339}
···18571857#define GET_BLOCK_CREATE 1 /* add anything you need to find block */18581858#define GET_BLOCK_NO_HOLE 2 /* return -ENOENT for file holes */18591859#define GET_BLOCK_READ_DIRECT 4 /* read the tail if indirect item not found */18601860-#define GET_BLOCK_NO_ISEM 8 /* i_sem is not held, don't preallocate */18601860+#define GET_BLOCK_NO_IMUX 8 /* i_mutex is not held, don't preallocate */18611861#define GET_BLOCK_NO_DANGLE 16 /* don't leave any transactions running */1862186218631863int restart_transaction(struct reiserfs_transaction_handle *th,
···15131513 struct dentry *dentry;15141514 int error;1515151515161516- down(&dir->d_inode->i_sem);15161516+ mutex_lock(&dir->d_inode->i_mutex);15171517 dentry = cpuset_get_dentry(dir, cft->name);15181518 if (!IS_ERR(dentry)) {15191519 error = cpuset_create_file(dentry, 0644 | S_IFREG);···15221522 dput(dentry);15231523 } else15241524 error = PTR_ERR(dentry);15251525- up(&dir->d_inode->i_sem);15251525+ mutex_unlock(&dir->d_inode->i_mutex);15261526 return error;15271527}15281528···1793179317941794 /*17951795 * Release manage_sem before cpuset_populate_dir() because it17961796- * will down() this new directory's i_sem and if we race with17961796+ * will down() this new directory's i_mutex and if we race with17971797 * another mkdir, we might deadlock.17981798 */17991799 up(&manage_sem);···18121812{18131813 struct cpuset *c_parent = dentry->d_parent->d_fsdata;1814181418151815- /* the vfs holds inode->i_sem already */18151815+ /* the vfs holds inode->i_mutex already */18161816 return cpuset_create(c_parent, dentry->d_name.name, mode | S_IFDIR);18171817}18181818···18231823 struct cpuset *parent;18241824 char *pathbuf = NULL;1825182518261826- /* the vfs holds both inode->i_sem already */18261826+ /* the vfs holds both inode->i_mutex already */1827182718281828 down(&manage_sem);18291829 cpuset_update_task_memory_state();
+5
kernel/exit.c
···2929#include <linux/syscalls.h>3030#include <linux/signal.h>3131#include <linux/cn_proc.h>3232+#include <linux/mutex.h>32333334#include <asm/uaccess.h>3435#include <asm/unistd.h>···870869 mpol_free(tsk->mempolicy);871870 tsk->mempolicy = NULL;872871#endif872872+ /*873873+ * If DEBUG_MUTEXES is on, make sure we are holding no locks:874874+ */875875+ mutex_debug_check_no_locks_held(tsk);873876874877 /* PF_DEAD causes final put_task_struct after we schedule. */875878 preempt_disable();
···11+/*22+ * kernel/mutex-debug.c33+ *44+ * Debugging code for mutexes55+ *66+ * Started by Ingo Molnar:77+ *88+ * Copyright (C) 2004, 2005, 2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>99+ *1010+ * lock debugging, locking tree, deadlock detection started by:1111+ *1212+ * Copyright (C) 2004, LynuxWorks, Inc., Igor Manyilov, Bill Huey1313+ * Released under the General Public License (GPL).1414+ */1515+#include <linux/mutex.h>1616+#include <linux/sched.h>1717+#include <linux/delay.h>1818+#include <linux/module.h>1919+#include <linux/spinlock.h>2020+#include <linux/kallsyms.h>2121+#include <linux/interrupt.h>2222+2323+#include <asm/mutex.h>2424+2525+#include "mutex-debug.h"2626+2727+/*2828+ * We need a global lock when we walk through the multi-process2929+ * lock tree. Only used in the deadlock-debugging case.3030+ */3131+DEFINE_SPINLOCK(debug_mutex_lock);3232+3333+/*3434+ * All locks held by all tasks, in a single global list:3535+ */3636+LIST_HEAD(debug_mutex_held_locks);3737+3838+/*3939+ * In the debug case we carry the caller's instruction pointer into4040+ * other functions, but we dont want the function argument overhead4141+ * in the nondebug case - hence these macros:4242+ */4343+#define __IP_DECL__ , unsigned long ip4444+#define __IP__ , ip4545+#define __RET_IP__ , (unsigned long)__builtin_return_address(0)4646+4747+/*4848+ * "mutex debugging enabled" flag. We turn it off when we detect4949+ * the first problem because we dont want to recurse back5050+ * into the tracing code when doing error printk or5151+ * executing a BUG():5252+ */5353+int debug_mutex_on = 1;5454+5555+static void printk_task(struct task_struct *p)5656+{5757+ if (p)5858+ printk("%16s:%5d [%p, %3d]", p->comm, p->pid, p, p->prio);5959+ else6060+ printk("<none>");6161+}6262+6363+static void printk_ti(struct thread_info *ti)6464+{6565+ if (ti)6666+ printk_task(ti->task);6767+ else6868+ printk("<none>");6969+}7070+7171+static void printk_task_short(struct task_struct *p)7272+{7373+ if (p)7474+ printk("%s/%d [%p, %3d]", p->comm, p->pid, p, p->prio);7575+ else7676+ printk("<none>");7777+}7878+7979+static void printk_lock(struct mutex *lock, int print_owner)8080+{8181+ printk(" [%p] {%s}\n", lock, lock->name);8282+8383+ if (print_owner && lock->owner) {8484+ printk(".. held by: ");8585+ printk_ti(lock->owner);8686+ printk("\n");8787+ }8888+ if (lock->owner) {8989+ printk("... acquired at: ");9090+ print_symbol("%s\n", lock->acquire_ip);9191+ }9292+}9393+9494+/*9595+ * printk locks held by a task:9696+ */9797+static void show_task_locks(struct task_struct *p)9898+{9999+ switch (p->state) {100100+ case TASK_RUNNING: printk("R"); break;101101+ case TASK_INTERRUPTIBLE: printk("S"); break;102102+ case TASK_UNINTERRUPTIBLE: printk("D"); break;103103+ case TASK_STOPPED: printk("T"); break;104104+ case EXIT_ZOMBIE: printk("Z"); break;105105+ case EXIT_DEAD: printk("X"); break;106106+ default: printk("?"); break;107107+ }108108+ printk_task(p);109109+ if (p->blocked_on) {110110+ struct mutex *lock = p->blocked_on->lock;111111+112112+ printk(" blocked on mutex:");113113+ printk_lock(lock, 1);114114+ } else115115+ printk(" (not blocked on mutex)\n");116116+}117117+118118+/*119119+ * printk all locks held in the system (if filter == NULL),120120+ * or all locks belonging to a single task (if filter != NULL):121121+ */122122+void show_held_locks(struct task_struct *filter)123123+{124124+ struct list_head *curr, *cursor = NULL;125125+ struct mutex *lock;126126+ struct thread_info *t;127127+ unsigned long flags;128128+ int count = 0;129129+130130+ if (filter) {131131+ printk("------------------------------\n");132132+ printk("| showing all locks held by: | (");133133+ printk_task_short(filter);134134+ printk("):\n");135135+ printk("------------------------------\n");136136+ } else {137137+ printk("---------------------------\n");138138+ printk("| showing all locks held: |\n");139139+ printk("---------------------------\n");140140+ }141141+142142+ /*143143+ * Play safe and acquire the global trace lock. We144144+ * cannot printk with that lock held so we iterate145145+ * very carefully:146146+ */147147+next:148148+ debug_spin_lock_save(&debug_mutex_lock, flags);149149+ list_for_each(curr, &debug_mutex_held_locks) {150150+ if (cursor && curr != cursor)151151+ continue;152152+ lock = list_entry(curr, struct mutex, held_list);153153+ t = lock->owner;154154+ if (filter && (t != filter->thread_info))155155+ continue;156156+ count++;157157+ cursor = curr->next;158158+ debug_spin_lock_restore(&debug_mutex_lock, flags);159159+160160+ printk("\n#%03d: ", count);161161+ printk_lock(lock, filter ? 0 : 1);162162+ goto next;163163+ }164164+ debug_spin_lock_restore(&debug_mutex_lock, flags);165165+ printk("\n");166166+}167167+168168+void mutex_debug_show_all_locks(void)169169+{170170+ struct task_struct *g, *p;171171+ int count = 10;172172+ int unlock = 1;173173+174174+ printk("\nShowing all blocking locks in the system:\n");175175+176176+ /*177177+ * Here we try to get the tasklist_lock as hard as possible,178178+ * if not successful after 2 seconds we ignore it (but keep179179+ * trying). This is to enable a debug printout even if a180180+ * tasklist_lock-holding task deadlocks or crashes.181181+ */182182+retry:183183+ if (!read_trylock(&tasklist_lock)) {184184+ if (count == 10)185185+ printk("hm, tasklist_lock locked, retrying... ");186186+ if (count) {187187+ count--;188188+ printk(" #%d", 10-count);189189+ mdelay(200);190190+ goto retry;191191+ }192192+ printk(" ignoring it.\n");193193+ unlock = 0;194194+ }195195+ if (count != 10)196196+ printk(" locked it.\n");197197+198198+ do_each_thread(g, p) {199199+ show_task_locks(p);200200+ if (!unlock)201201+ if (read_trylock(&tasklist_lock))202202+ unlock = 1;203203+ } while_each_thread(g, p);204204+205205+ printk("\n");206206+ show_held_locks(NULL);207207+ printk("=============================================\n\n");208208+209209+ if (unlock)210210+ read_unlock(&tasklist_lock);211211+}212212+213213+static void report_deadlock(struct task_struct *task, struct mutex *lock,214214+ struct mutex *lockblk, unsigned long ip)215215+{216216+ printk("\n%s/%d is trying to acquire this lock:\n",217217+ current->comm, current->pid);218218+ printk_lock(lock, 1);219219+ printk("... trying at: ");220220+ print_symbol("%s\n", ip);221221+ show_held_locks(current);222222+223223+ if (lockblk) {224224+ printk("but %s/%d is deadlocking current task %s/%d!\n\n",225225+ task->comm, task->pid, current->comm, current->pid);226226+ printk("\n%s/%d is blocked on this lock:\n",227227+ task->comm, task->pid);228228+ printk_lock(lockblk, 1);229229+230230+ show_held_locks(task);231231+232232+ printk("\n%s/%d's [blocked] stackdump:\n\n",233233+ task->comm, task->pid);234234+ show_stack(task, NULL);235235+ }236236+237237+ printk("\n%s/%d's [current] stackdump:\n\n",238238+ current->comm, current->pid);239239+ dump_stack();240240+ mutex_debug_show_all_locks();241241+ printk("[ turning off deadlock detection. Please report this. ]\n\n");242242+ local_irq_disable();243243+}244244+245245+/*246246+ * Recursively check for mutex deadlocks:247247+ */248248+static int check_deadlock(struct mutex *lock, int depth,249249+ struct thread_info *ti, unsigned long ip)250250+{251251+ struct mutex *lockblk;252252+ struct task_struct *task;253253+254254+ if (!debug_mutex_on)255255+ return 0;256256+257257+ ti = lock->owner;258258+ if (!ti)259259+ return 0;260260+261261+ task = ti->task;262262+ lockblk = NULL;263263+ if (task->blocked_on)264264+ lockblk = task->blocked_on->lock;265265+266266+ /* Self-deadlock: */267267+ if (current == task) {268268+ DEBUG_OFF();269269+ if (depth)270270+ return 1;271271+ printk("\n==========================================\n");272272+ printk( "[ BUG: lock recursion deadlock detected! |\n");273273+ printk( "------------------------------------------\n");274274+ report_deadlock(task, lock, NULL, ip);275275+ return 0;276276+ }277277+278278+ /* Ugh, something corrupted the lock data structure? */279279+ if (depth > 20) {280280+ DEBUG_OFF();281281+ printk("\n===========================================\n");282282+ printk( "[ BUG: infinite lock dependency detected!? |\n");283283+ printk( "-------------------------------------------\n");284284+ report_deadlock(task, lock, lockblk, ip);285285+ return 0;286286+ }287287+288288+ /* Recursively check for dependencies: */289289+ if (lockblk && check_deadlock(lockblk, depth+1, ti, ip)) {290290+ printk("\n============================================\n");291291+ printk( "[ BUG: circular locking deadlock detected! ]\n");292292+ printk( "--------------------------------------------\n");293293+ report_deadlock(task, lock, lockblk, ip);294294+ return 0;295295+ }296296+ return 0;297297+}298298+299299+/*300300+ * Called when a task exits, this function checks whether the301301+ * task is holding any locks, and reports the first one if so:302302+ */303303+void mutex_debug_check_no_locks_held(struct task_struct *task)304304+{305305+ struct list_head *curr, *next;306306+ struct thread_info *t;307307+ unsigned long flags;308308+ struct mutex *lock;309309+310310+ if (!debug_mutex_on)311311+ return;312312+313313+ debug_spin_lock_save(&debug_mutex_lock, flags);314314+ list_for_each_safe(curr, next, &debug_mutex_held_locks) {315315+ lock = list_entry(curr, struct mutex, held_list);316316+ t = lock->owner;317317+ if (t != task->thread_info)318318+ continue;319319+ list_del_init(curr);320320+ DEBUG_OFF();321321+ debug_spin_lock_restore(&debug_mutex_lock, flags);322322+323323+ printk("BUG: %s/%d, lock held at task exit time!\n",324324+ task->comm, task->pid);325325+ printk_lock(lock, 1);326326+ if (lock->owner != task->thread_info)327327+ printk("exiting task is not even the owner??\n");328328+ return;329329+ }330330+ debug_spin_lock_restore(&debug_mutex_lock, flags);331331+}332332+333333+/*334334+ * Called when kernel memory is freed (or unmapped), or if a mutex335335+ * is destroyed or reinitialized - this code checks whether there is336336+ * any held lock in the memory range of <from> to <to>:337337+ */338338+void mutex_debug_check_no_locks_freed(const void *from, const void *to)339339+{340340+ struct list_head *curr, *next;341341+ unsigned long flags;342342+ struct mutex *lock;343343+ void *lock_addr;344344+345345+ if (!debug_mutex_on)346346+ return;347347+348348+ debug_spin_lock_save(&debug_mutex_lock, flags);349349+ list_for_each_safe(curr, next, &debug_mutex_held_locks) {350350+ lock = list_entry(curr, struct mutex, held_list);351351+ lock_addr = lock;352352+ if (lock_addr < from || lock_addr >= to)353353+ continue;354354+ list_del_init(curr);355355+ DEBUG_OFF();356356+ debug_spin_lock_restore(&debug_mutex_lock, flags);357357+358358+ printk("BUG: %s/%d, active lock [%p(%p-%p)] freed!\n",359359+ current->comm, current->pid, lock, from, to);360360+ dump_stack();361361+ printk_lock(lock, 1);362362+ if (lock->owner != current_thread_info())363363+ printk("freeing task is not even the owner??\n");364364+ return;365365+ }366366+ debug_spin_lock_restore(&debug_mutex_lock, flags);367367+}368368+369369+/*370370+ * Must be called with lock->wait_lock held.371371+ */372372+void debug_mutex_set_owner(struct mutex *lock,373373+ struct thread_info *new_owner __IP_DECL__)374374+{375375+ lock->owner = new_owner;376376+ DEBUG_WARN_ON(!list_empty(&lock->held_list));377377+ if (debug_mutex_on) {378378+ list_add_tail(&lock->held_list, &debug_mutex_held_locks);379379+ lock->acquire_ip = ip;380380+ }381381+}382382+383383+void debug_mutex_init_waiter(struct mutex_waiter *waiter)384384+{385385+ memset(waiter, 0x11, sizeof(*waiter));386386+ waiter->magic = waiter;387387+ INIT_LIST_HEAD(&waiter->list);388388+}389389+390390+void debug_mutex_wake_waiter(struct mutex *lock, struct mutex_waiter *waiter)391391+{392392+ SMP_DEBUG_WARN_ON(!spin_is_locked(&lock->wait_lock));393393+ DEBUG_WARN_ON(list_empty(&lock->wait_list));394394+ DEBUG_WARN_ON(waiter->magic != waiter);395395+ DEBUG_WARN_ON(list_empty(&waiter->list));396396+}397397+398398+void debug_mutex_free_waiter(struct mutex_waiter *waiter)399399+{400400+ DEBUG_WARN_ON(!list_empty(&waiter->list));401401+ memset(waiter, 0x22, sizeof(*waiter));402402+}403403+404404+void debug_mutex_add_waiter(struct mutex *lock, struct mutex_waiter *waiter,405405+ struct thread_info *ti __IP_DECL__)406406+{407407+ SMP_DEBUG_WARN_ON(!spin_is_locked(&lock->wait_lock));408408+ check_deadlock(lock, 0, ti, ip);409409+ /* Mark the current thread as blocked on the lock: */410410+ ti->task->blocked_on = waiter;411411+ waiter->lock = lock;412412+}413413+414414+void mutex_remove_waiter(struct mutex *lock, struct mutex_waiter *waiter,415415+ struct thread_info *ti)416416+{417417+ DEBUG_WARN_ON(list_empty(&waiter->list));418418+ DEBUG_WARN_ON(waiter->task != ti->task);419419+ DEBUG_WARN_ON(ti->task->blocked_on != waiter);420420+ ti->task->blocked_on = NULL;421421+422422+ list_del_init(&waiter->list);423423+ waiter->task = NULL;424424+}425425+426426+void debug_mutex_unlock(struct mutex *lock)427427+{428428+ DEBUG_WARN_ON(lock->magic != lock);429429+ DEBUG_WARN_ON(!lock->wait_list.prev && !lock->wait_list.next);430430+ DEBUG_WARN_ON(lock->owner != current_thread_info());431431+ if (debug_mutex_on) {432432+ DEBUG_WARN_ON(list_empty(&lock->held_list));433433+ list_del_init(&lock->held_list);434434+ }435435+}436436+437437+void debug_mutex_init(struct mutex *lock, const char *name)438438+{439439+ /*440440+ * Make sure we are not reinitializing a held lock:441441+ */442442+ mutex_debug_check_no_locks_freed((void *)lock, (void *)(lock + 1));443443+ lock->owner = NULL;444444+ INIT_LIST_HEAD(&lock->held_list);445445+ lock->name = name;446446+ lock->magic = lock;447447+}448448+449449+/***450450+ * mutex_destroy - mark a mutex unusable451451+ * @lock: the mutex to be destroyed452452+ *453453+ * This function marks the mutex uninitialized, and any subsequent454454+ * use of the mutex is forbidden. The mutex must not be locked when455455+ * this function is called.456456+ */457457+void fastcall mutex_destroy(struct mutex *lock)458458+{459459+ DEBUG_WARN_ON(mutex_is_locked(lock));460460+ lock->magic = NULL;461461+}462462+463463+EXPORT_SYMBOL_GPL(mutex_destroy);464464+
+134
kernel/mutex-debug.h
···11+/*22+ * Mutexes: blocking mutual exclusion locks33+ *44+ * started by Ingo Molnar:55+ *66+ * Copyright (C) 2004, 2005, 2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>77+ *88+ * This file contains mutex debugging related internal declarations,99+ * prototypes and inline functions, for the CONFIG_DEBUG_MUTEXES case.1010+ * More details are in kernel/mutex-debug.c.1111+ */1212+1313+extern spinlock_t debug_mutex_lock;1414+extern struct list_head debug_mutex_held_locks;1515+extern int debug_mutex_on;1616+1717+/*1818+ * In the debug case we carry the caller's instruction pointer into1919+ * other functions, but we dont want the function argument overhead2020+ * in the nondebug case - hence these macros:2121+ */2222+#define __IP_DECL__ , unsigned long ip2323+#define __IP__ , ip2424+#define __RET_IP__ , (unsigned long)__builtin_return_address(0)2525+2626+/*2727+ * This must be called with lock->wait_lock held.2828+ */2929+extern void debug_mutex_set_owner(struct mutex *lock,3030+ struct thread_info *new_owner __IP_DECL__);3131+3232+static inline void debug_mutex_clear_owner(struct mutex *lock)3333+{3434+ lock->owner = NULL;3535+}3636+3737+extern void debug_mutex_init_waiter(struct mutex_waiter *waiter);3838+extern void debug_mutex_wake_waiter(struct mutex *lock,3939+ struct mutex_waiter *waiter);4040+extern void debug_mutex_free_waiter(struct mutex_waiter *waiter);4141+extern void debug_mutex_add_waiter(struct mutex *lock,4242+ struct mutex_waiter *waiter,4343+ struct thread_info *ti __IP_DECL__);4444+extern void mutex_remove_waiter(struct mutex *lock, struct mutex_waiter *waiter,4545+ struct thread_info *ti);4646+extern void debug_mutex_unlock(struct mutex *lock);4747+extern void debug_mutex_init(struct mutex *lock, const char *name);4848+4949+#define debug_spin_lock(lock) \5050+ do { \5151+ local_irq_disable(); \5252+ if (debug_mutex_on) \5353+ spin_lock(lock); \5454+ } while (0)5555+5656+#define debug_spin_unlock(lock) \5757+ do { \5858+ if (debug_mutex_on) \5959+ spin_unlock(lock); \6060+ local_irq_enable(); \6161+ preempt_check_resched(); \6262+ } while (0)6363+6464+#define debug_spin_lock_save(lock, flags) \6565+ do { \6666+ local_irq_save(flags); \6767+ if (debug_mutex_on) \6868+ spin_lock(lock); \6969+ } while (0)7070+7171+#define debug_spin_lock_restore(lock, flags) \7272+ do { \7373+ if (debug_mutex_on) \7474+ spin_unlock(lock); \7575+ local_irq_restore(flags); \7676+ preempt_check_resched(); \7777+ } while (0)7878+7979+#define spin_lock_mutex(lock) \8080+ do { \8181+ struct mutex *l = container_of(lock, struct mutex, wait_lock); \8282+ \8383+ DEBUG_WARN_ON(in_interrupt()); \8484+ debug_spin_lock(&debug_mutex_lock); \8585+ spin_lock(lock); \8686+ DEBUG_WARN_ON(l->magic != l); \8787+ } while (0)8888+8989+#define spin_unlock_mutex(lock) \9090+ do { \9191+ spin_unlock(lock); \9292+ debug_spin_unlock(&debug_mutex_lock); \9393+ } while (0)9494+9595+#define DEBUG_OFF() \9696+do { \9797+ if (debug_mutex_on) { \9898+ debug_mutex_on = 0; \9999+ console_verbose(); \100100+ if (spin_is_locked(&debug_mutex_lock)) \101101+ spin_unlock(&debug_mutex_lock); \102102+ } \103103+} while (0)104104+105105+#define DEBUG_BUG() \106106+do { \107107+ if (debug_mutex_on) { \108108+ DEBUG_OFF(); \109109+ BUG(); \110110+ } \111111+} while (0)112112+113113+#define DEBUG_WARN_ON(c) \114114+do { \115115+ if (unlikely(c && debug_mutex_on)) { \116116+ DEBUG_OFF(); \117117+ WARN_ON(1); \118118+ } \119119+} while (0)120120+121121+# define DEBUG_BUG_ON(c) \122122+do { \123123+ if (unlikely(c)) \124124+ DEBUG_BUG(); \125125+} while (0)126126+127127+#ifdef CONFIG_SMP128128+# define SMP_DEBUG_WARN_ON(c) DEBUG_WARN_ON(c)129129+# define SMP_DEBUG_BUG_ON(c) DEBUG_BUG_ON(c)130130+#else131131+# define SMP_DEBUG_WARN_ON(c) do { } while (0)132132+# define SMP_DEBUG_BUG_ON(c) do { } while (0)133133+#endif134134+
+325
kernel/mutex.c
···11+/*22+ * kernel/mutex.c33+ *44+ * Mutexes: blocking mutual exclusion locks55+ *66+ * Started by Ingo Molnar:77+ *88+ * Copyright (C) 2004, 2005, 2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>99+ *1010+ * Many thanks to Arjan van de Ven, Thomas Gleixner, Steven Rostedt and1111+ * David Howells for suggestions and improvements.1212+ *1313+ * Also see Documentation/mutex-design.txt.1414+ */1515+#include <linux/mutex.h>1616+#include <linux/sched.h>1717+#include <linux/module.h>1818+#include <linux/spinlock.h>1919+#include <linux/interrupt.h>2020+2121+/*2222+ * In the DEBUG case we are using the "NULL fastpath" for mutexes,2323+ * which forces all calls into the slowpath:2424+ */2525+#ifdef CONFIG_DEBUG_MUTEXES2626+# include "mutex-debug.h"2727+# include <asm-generic/mutex-null.h>2828+#else2929+# include "mutex.h"3030+# include <asm/mutex.h>3131+#endif3232+3333+/***3434+ * mutex_init - initialize the mutex3535+ * @lock: the mutex to be initialized3636+ *3737+ * Initialize the mutex to unlocked state.3838+ *3939+ * It is not allowed to initialize an already locked mutex.4040+ */4141+void fastcall __mutex_init(struct mutex *lock, const char *name)4242+{4343+ atomic_set(&lock->count, 1);4444+ spin_lock_init(&lock->wait_lock);4545+ INIT_LIST_HEAD(&lock->wait_list);4646+4747+ debug_mutex_init(lock, name);4848+}4949+5050+EXPORT_SYMBOL(__mutex_init);5151+5252+/*5353+ * We split the mutex lock/unlock logic into separate fastpath and5454+ * slowpath functions, to reduce the register pressure on the fastpath.5555+ * We also put the fastpath first in the kernel image, to make sure the5656+ * branch is predicted by the CPU as default-untaken.5757+ */5858+static void fastcall noinline __sched5959+__mutex_lock_slowpath(atomic_t *lock_count __IP_DECL__);6060+6161+/***6262+ * mutex_lock - acquire the mutex6363+ * @lock: the mutex to be acquired6464+ *6565+ * Lock the mutex exclusively for this task. If the mutex is not6666+ * available right now, it will sleep until it can get it.6767+ *6868+ * The mutex must later on be released by the same task that6969+ * acquired it. Recursive locking is not allowed. The task7070+ * may not exit without first unlocking the mutex. Also, kernel7171+ * memory where the mutex resides mutex must not be freed with7272+ * the mutex still locked. The mutex must first be initialized7373+ * (or statically defined) before it can be locked. memset()-ing7474+ * the mutex to 0 is not allowed.7575+ *7676+ * ( The CONFIG_DEBUG_MUTEXES .config option turns on debugging7777+ * checks that will enforce the restrictions and will also do7878+ * deadlock debugging. )7979+ *8080+ * This function is similar to (but not equivalent to) down().8181+ */8282+void fastcall __sched mutex_lock(struct mutex *lock)8383+{8484+ /*8585+ * The locking fastpath is the 1->0 transition from8686+ * 'unlocked' into 'locked' state.8787+ *8888+ * NOTE: if asm/mutex.h is included, then some architectures8989+ * rely on mutex_lock() having _no other code_ here but this9090+ * fastpath. That allows the assembly fastpath to do9191+ * tail-merging optimizations. (If you want to put testcode9292+ * here, do it under #ifndef CONFIG_MUTEX_DEBUG.)9393+ */9494+ __mutex_fastpath_lock(&lock->count, __mutex_lock_slowpath);9595+}9696+9797+EXPORT_SYMBOL(mutex_lock);9898+9999+static void fastcall noinline __sched100100+__mutex_unlock_slowpath(atomic_t *lock_count __IP_DECL__);101101+102102+/***103103+ * mutex_unlock - release the mutex104104+ * @lock: the mutex to be released105105+ *106106+ * Unlock a mutex that has been locked by this task previously.107107+ *108108+ * This function must not be used in interrupt context. Unlocking109109+ * of a not locked mutex is not allowed.110110+ *111111+ * This function is similar to (but not equivalent to) up().112112+ */113113+void fastcall __sched mutex_unlock(struct mutex *lock)114114+{115115+ /*116116+ * The unlocking fastpath is the 0->1 transition from 'locked'117117+ * into 'unlocked' state:118118+ *119119+ * NOTE: no other code must be here - see mutex_lock() .120120+ */121121+ __mutex_fastpath_unlock(&lock->count, __mutex_unlock_slowpath);122122+}123123+124124+EXPORT_SYMBOL(mutex_unlock);125125+126126+/*127127+ * Lock a mutex (possibly interruptible), slowpath:128128+ */129129+static inline int __sched130130+__mutex_lock_common(struct mutex *lock, long state __IP_DECL__)131131+{132132+ struct task_struct *task = current;133133+ struct mutex_waiter waiter;134134+ unsigned int old_val;135135+136136+ debug_mutex_init_waiter(&waiter);137137+138138+ spin_lock_mutex(&lock->wait_lock);139139+140140+ debug_mutex_add_waiter(lock, &waiter, task->thread_info, ip);141141+142142+ /* add waiting tasks to the end of the waitqueue (FIFO): */143143+ list_add_tail(&waiter.list, &lock->wait_list);144144+ waiter.task = task;145145+146146+ for (;;) {147147+ /*148148+ * Lets try to take the lock again - this is needed even if149149+ * we get here for the first time (shortly after failing to150150+ * acquire the lock), to make sure that we get a wakeup once151151+ * it's unlocked. Later on, if we sleep, this is the152152+ * operation that gives us the lock. We xchg it to -1, so153153+ * that when we release the lock, we properly wake up the154154+ * other waiters:155155+ */156156+ old_val = atomic_xchg(&lock->count, -1);157157+ if (old_val == 1)158158+ break;159159+160160+ /*161161+ * got a signal? (This code gets eliminated in the162162+ * TASK_UNINTERRUPTIBLE case.)163163+ */164164+ if (unlikely(state == TASK_INTERRUPTIBLE &&165165+ signal_pending(task))) {166166+ mutex_remove_waiter(lock, &waiter, task->thread_info);167167+ spin_unlock_mutex(&lock->wait_lock);168168+169169+ debug_mutex_free_waiter(&waiter);170170+ return -EINTR;171171+ }172172+ __set_task_state(task, state);173173+174174+ /* didnt get the lock, go to sleep: */175175+ spin_unlock_mutex(&lock->wait_lock);176176+ schedule();177177+ spin_lock_mutex(&lock->wait_lock);178178+ }179179+180180+ /* got the lock - rejoice! */181181+ mutex_remove_waiter(lock, &waiter, task->thread_info);182182+ debug_mutex_set_owner(lock, task->thread_info __IP__);183183+184184+ /* set it to 0 if there are no waiters left: */185185+ if (likely(list_empty(&lock->wait_list)))186186+ atomic_set(&lock->count, 0);187187+188188+ spin_unlock_mutex(&lock->wait_lock);189189+190190+ debug_mutex_free_waiter(&waiter);191191+192192+ DEBUG_WARN_ON(list_empty(&lock->held_list));193193+ DEBUG_WARN_ON(lock->owner != task->thread_info);194194+195195+ return 0;196196+}197197+198198+static void fastcall noinline __sched199199+__mutex_lock_slowpath(atomic_t *lock_count __IP_DECL__)200200+{201201+ struct mutex *lock = container_of(lock_count, struct mutex, count);202202+203203+ __mutex_lock_common(lock, TASK_UNINTERRUPTIBLE __IP__);204204+}205205+206206+/*207207+ * Release the lock, slowpath:208208+ */209209+static fastcall noinline void210210+__mutex_unlock_slowpath(atomic_t *lock_count __IP_DECL__)211211+{212212+ struct mutex *lock = container_of(lock_count, struct mutex, count);213213+214214+ DEBUG_WARN_ON(lock->owner != current_thread_info());215215+216216+ spin_lock_mutex(&lock->wait_lock);217217+218218+ /*219219+ * some architectures leave the lock unlocked in the fastpath failure220220+ * case, others need to leave it locked. In the later case we have to221221+ * unlock it here222222+ */223223+ if (__mutex_slowpath_needs_to_unlock())224224+ atomic_set(&lock->count, 1);225225+226226+ debug_mutex_unlock(lock);227227+228228+ if (!list_empty(&lock->wait_list)) {229229+ /* get the first entry from the wait-list: */230230+ struct mutex_waiter *waiter =231231+ list_entry(lock->wait_list.next,232232+ struct mutex_waiter, list);233233+234234+ debug_mutex_wake_waiter(lock, waiter);235235+236236+ wake_up_process(waiter->task);237237+ }238238+239239+ debug_mutex_clear_owner(lock);240240+241241+ spin_unlock_mutex(&lock->wait_lock);242242+}243243+244244+/*245245+ * Here come the less common (and hence less performance-critical) APIs:246246+ * mutex_lock_interruptible() and mutex_trylock().247247+ */248248+static int fastcall noinline __sched249249+__mutex_lock_interruptible_slowpath(atomic_t *lock_count __IP_DECL__);250250+251251+/***252252+ * mutex_lock_interruptible - acquire the mutex, interruptable253253+ * @lock: the mutex to be acquired254254+ *255255+ * Lock the mutex like mutex_lock(), and return 0 if the mutex has256256+ * been acquired or sleep until the mutex becomes available. If a257257+ * signal arrives while waiting for the lock then this function258258+ * returns -EINTR.259259+ *260260+ * This function is similar to (but not equivalent to) down_interruptible().261261+ */262262+int fastcall __sched mutex_lock_interruptible(struct mutex *lock)263263+{264264+ /* NOTE: no other code must be here - see mutex_lock() */265265+ return __mutex_fastpath_lock_retval266266+ (&lock->count, __mutex_lock_interruptible_slowpath);267267+}268268+269269+EXPORT_SYMBOL(mutex_lock_interruptible);270270+271271+static int fastcall noinline __sched272272+__mutex_lock_interruptible_slowpath(atomic_t *lock_count __IP_DECL__)273273+{274274+ struct mutex *lock = container_of(lock_count, struct mutex, count);275275+276276+ return __mutex_lock_common(lock, TASK_INTERRUPTIBLE __IP__);277277+}278278+279279+/*280280+ * Spinlock based trylock, we take the spinlock and check whether we281281+ * can get the lock:282282+ */283283+static inline int __mutex_trylock_slowpath(atomic_t *lock_count)284284+{285285+ struct mutex *lock = container_of(lock_count, struct mutex, count);286286+ int prev;287287+288288+ spin_lock_mutex(&lock->wait_lock);289289+290290+ prev = atomic_xchg(&lock->count, -1);291291+ if (likely(prev == 1))292292+ debug_mutex_set_owner(lock, current_thread_info() __RET_IP__);293293+ /* Set it back to 0 if there are no waiters: */294294+ if (likely(list_empty(&lock->wait_list)))295295+ atomic_set(&lock->count, 0);296296+297297+ spin_unlock_mutex(&lock->wait_lock);298298+299299+ return prev == 1;300300+}301301+302302+/***303303+ * mutex_trylock - try acquire the mutex, without waiting304304+ * @lock: the mutex to be acquired305305+ *306306+ * Try to acquire the mutex atomically. Returns 1 if the mutex307307+ * has been acquired successfully, and 0 on contention.308308+ *309309+ * NOTE: this function follows the spin_trylock() convention, so310310+ * it is negated to the down_trylock() return values! Be careful311311+ * about this when converting semaphore users to mutexes.312312+ *313313+ * This function must not be used in interrupt context. The314314+ * mutex must be released by the same task that acquired it.315315+ */316316+int fastcall mutex_trylock(struct mutex *lock)317317+{318318+ return __mutex_fastpath_trylock(&lock->count,319319+ __mutex_trylock_slowpath);320320+}321321+322322+EXPORT_SYMBOL(mutex_trylock);323323+324324+325325+
+35
kernel/mutex.h
···11+/*22+ * Mutexes: blocking mutual exclusion locks33+ *44+ * started by Ingo Molnar:55+ *66+ * Copyright (C) 2004, 2005, 2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>77+ *88+ * This file contains mutex debugging related internal prototypes, for the99+ * !CONFIG_DEBUG_MUTEXES case. Most of them are NOPs:1010+ */1111+1212+#define spin_lock_mutex(lock) spin_lock(lock)1313+#define spin_unlock_mutex(lock) spin_unlock(lock)1414+#define mutex_remove_waiter(lock, waiter, ti) \1515+ __list_del((waiter)->list.prev, (waiter)->list.next)1616+1717+#define DEBUG_WARN_ON(c) do { } while (0)1818+#define debug_mutex_set_owner(lock, new_owner) do { } while (0)1919+#define debug_mutex_clear_owner(lock) do { } while (0)2020+#define debug_mutex_init_waiter(waiter) do { } while (0)2121+#define debug_mutex_wake_waiter(lock, waiter) do { } while (0)2222+#define debug_mutex_free_waiter(waiter) do { } while (0)2323+#define debug_mutex_add_waiter(lock, waiter, ti, ip) do { } while (0)2424+#define debug_mutex_unlock(lock) do { } while (0)2525+#define debug_mutex_init(lock, name) do { } while (0)2626+2727+/*2828+ * Return-address parameters/declarations. They are very useful for2929+ * debugging, but add overhead in the !DEBUG case - so we go the3030+ * trouble of using this not too elegant but zero-cost solution:3131+ */3232+#define __IP_DECL__3333+#define __IP__3434+#define __RET_IP__3535+
···9595 if kernel code uses it in a preemption-unsafe way. Also, the kernel9696 will detect preemption count underflows.97979898+config DEBUG_MUTEXES9999+ bool "Mutex debugging, deadlock detection"100100+ default y101101+ depends on DEBUG_KERNEL102102+ help103103+ This allows mutex semantics violations and mutex related deadlocks104104+ (lockups) to be detected and reported automatically.105105+98106config DEBUG_SPINLOCK99107 bool "Spinlock debugging"100108 depends on DEBUG_KERNEL
+15-15
mm/filemap.c
···6161 * ->swap_lock (exclusive_swap_page, others)6262 * ->mapping->tree_lock6363 *6464- * ->i_sem6464+ * ->i_mutex6565 * ->i_mmap_lock (truncate->unmap_mapping_range)6666 *6767 * ->mmap_sem···7373 * ->lock_page (access_process_vm)7474 *7575 * ->mmap_sem7676- * ->i_sem (msync)7676+ * ->i_mutex (msync)7777 *7878- * ->i_sem7878+ * ->i_mutex7979 * ->i_alloc_sem (various)8080 *8181 * ->inode_lock···276276 * integrity" operation. It waits upon in-flight writeout before starting and277277 * waiting upon new writeout. If there was an IO error, return it.278278 *279279- * We need to re-take i_sem during the generic_osync_inode list walk because279279+ * We need to re-take i_mutex during the generic_osync_inode list walk because280280 * it is otherwise livelockable.281281 */282282int sync_page_range(struct inode *inode, struct address_space *mapping,···290290 return 0;291291 ret = filemap_fdatawrite_range(mapping, pos, pos + count - 1);292292 if (ret == 0) {293293- down(&inode->i_sem);293293+ mutex_lock(&inode->i_mutex);294294 ret = generic_osync_inode(inode, mapping, OSYNC_METADATA);295295- up(&inode->i_sem);295295+ mutex_unlock(&inode->i_mutex);296296 }297297 if (ret == 0)298298 ret = wait_on_page_writeback_range(mapping, start, end);···301301EXPORT_SYMBOL(sync_page_range);302302303303/*304304- * Note: Holding i_sem across sync_page_range_nolock is not a good idea304304+ * Note: Holding i_mutex across sync_page_range_nolock is not a good idea305305 * as it forces O_SYNC writers to different parts of the same file306306 * to be serialised right until io completion.307307 */···18921892 /*18931893 * Sync the fs metadata but not the minor inode changes and18941894 * of course not the data as we did direct DMA for the IO.18951895- * i_sem is held, which protects generic_osync_inode() from18951895+ * i_mutex is held, which protects generic_osync_inode() from18961896 * livelocking.18971897 */18981898 if (written >= 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) {···2195219521962196 BUG_ON(iocb->ki_pos != pos);2197219721982198- down(&inode->i_sem);21982198+ mutex_lock(&inode->i_mutex);21992199 ret = __generic_file_aio_write_nolock(iocb, &local_iov, 1,22002200 &iocb->ki_pos);22012201- up(&inode->i_sem);22012201+ mutex_unlock(&inode->i_mutex);2202220222032203 if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) {22042204 ssize_t err;···22202220 struct iovec local_iov = { .iov_base = (void __user *)buf,22212221 .iov_len = count };2222222222232223- down(&inode->i_sem);22232223+ mutex_lock(&inode->i_mutex);22242224 ret = __generic_file_write_nolock(file, &local_iov, 1, ppos);22252225- up(&inode->i_sem);22252225+ mutex_unlock(&inode->i_mutex);2226222622272227 if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) {22282228 ssize_t err;···22562256 struct inode *inode = mapping->host;22572257 ssize_t ret;2258225822592259- down(&inode->i_sem);22592259+ mutex_lock(&inode->i_mutex);22602260 ret = __generic_file_write_nolock(file, iov, nr_segs, ppos);22612261- up(&inode->i_sem);22612261+ mutex_unlock(&inode->i_mutex);2262226222632263 if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) {22642264 int err;···22722272EXPORT_SYMBOL(generic_file_writev);2273227322742274/*22752275- * Called under i_sem for writes to S_ISREG files. Returns -EIO if something22752275+ * Called under i_mutex for writes to S_ISREG files. Returns -EIO if something22762276 * went wrong during pagecache shootdown.22772277 */22782278static ssize_t
+3-3
mm/filemap_xip.c
···338338 *ppos = pos;339339 /*340340 * No need to use i_size_read() here, the i_size341341- * cannot change under us because we hold i_sem.341341+ * cannot change under us because we hold i_mutex.342342 */343343 if (pos > inode->i_size) {344344 i_size_write(inode, pos);···358358 loff_t pos;359359 ssize_t ret;360360361361- down(&inode->i_sem);361361+ mutex_lock(&inode->i_mutex);362362363363 if (!access_ok(VERIFY_READ, buf, len)) {364364 ret=-EFAULT;···390390 out_backing:391391 current->backing_dev_info = NULL;392392 out_up:393393- up(&inode->i_sem);393393+ mutex_unlock(&inode->i_mutex);394394 return ret;395395}396396EXPORT_SYMBOL_GPL(xip_file_write);
···137137 ret = filemap_fdatawrite(mapping);138138 if (file->f_op && file->f_op->fsync) {139139 /*140140- * We don't take i_sem here because mmap_sem140140+ * We don't take i_mutex here because mmap_sem141141 * is already held.142142 */143143 err = file->f_op->fsync(file,file->f_dentry,1);
+3
mm/page_alloc.c
···415415 int reserved = 0;416416417417 arch_free_page(page, order);418418+ if (!PageHighMem(page))419419+ mutex_debug_check_no_locks_freed(page_address(page),420420+ page_address(page+(1<<order)));418421419422#ifndef CONFIG_MMU420423 for (i = 1 ; i < (1 << order) ; ++i)
+4-4
mm/rmap.c
···2020/*2121 * Lock ordering in mm:2222 *2323- * inode->i_sem (while writing or truncating, not reading or faulting)2323+ * inode->i_mutex (while writing or truncating, not reading or faulting)2424 * inode->i_alloc_sem2525 *2626 * When a page fault occurs in writing from user to file, down_read2727- * of mmap_sem nests within i_sem; in sys_msync, i_sem nests within2828- * down_read of mmap_sem; i_sem and down_write of mmap_sem are never2929- * taken together; in truncation, i_sem is taken outermost.2727+ * of mmap_sem nests within i_mutex; in sys_msync, i_mutex nests within2828+ * down_read of mmap_sem; i_mutex and down_write of mmap_sem are never2929+ * taken together; in truncation, i_mutex is taken outermost.3030 *3131 * mm->mmap_sem3232 * page->flags PG_locked (lock_page)
···196196 * @mapping: mapping to truncate197197 * @lstart: offset from which to truncate198198 *199199- * Called under (and serialised by) inode->i_sem.199199+ * Called under (and serialised by) inode->i_mutex.200200 */201201void truncate_inode_pages(struct address_space *mapping, loff_t lstart)202202{
+29-29
net/sunrpc/rpc_pipe.c
···6969 struct rpc_inode *rpci = (struct rpc_inode *)data;7070 struct inode *inode = &rpci->vfs_inode;71717272- down(&inode->i_sem);7272+ mutex_lock(&inode->i_mutex);7373 if (rpci->ops == NULL)7474 goto out;7575 if (rpci->nreaders == 0 && !list_empty(&rpci->pipe))7676 __rpc_purge_upcall(inode, -ETIMEDOUT);7777out:7878- up(&inode->i_sem);7878+ mutex_unlock(&inode->i_mutex);7979}80808181int···8484 struct rpc_inode *rpci = RPC_I(inode);8585 int res = -EPIPE;86868787- down(&inode->i_sem);8787+ mutex_lock(&inode->i_mutex);8888 if (rpci->ops == NULL)8989 goto out;9090 if (rpci->nreaders) {···100100 res = 0;101101 }102102out:103103- up(&inode->i_sem);103103+ mutex_unlock(&inode->i_mutex);104104 wake_up(&rpci->waitq);105105 return res;106106}···116116{117117 struct rpc_inode *rpci = RPC_I(inode);118118119119- down(&inode->i_sem);119119+ mutex_lock(&inode->i_mutex);120120 if (rpci->ops != NULL) {121121 rpci->nreaders = 0;122122 __rpc_purge_list(rpci, &rpci->in_upcall, -EPIPE);···127127 rpci->ops = NULL;128128 }129129 rpc_inode_setowner(inode, NULL);130130- up(&inode->i_sem);130130+ mutex_unlock(&inode->i_mutex);131131 cancel_delayed_work(&rpci->queue_timeout);132132 flush_scheduled_work();133133}···154154 struct rpc_inode *rpci = RPC_I(inode);155155 int res = -ENXIO;156156157157- down(&inode->i_sem);157157+ mutex_lock(&inode->i_mutex);158158 if (rpci->ops != NULL) {159159 if (filp->f_mode & FMODE_READ)160160 rpci->nreaders ++;···162162 rpci->nwriters ++;163163 res = 0;164164 }165165- up(&inode->i_sem);165165+ mutex_unlock(&inode->i_mutex);166166 return res;167167}168168···172172 struct rpc_inode *rpci = RPC_I(inode);173173 struct rpc_pipe_msg *msg;174174175175- down(&inode->i_sem);175175+ mutex_lock(&inode->i_mutex);176176 if (rpci->ops == NULL)177177 goto out;178178 msg = (struct rpc_pipe_msg *)filp->private_data;···190190 if (rpci->ops->release_pipe)191191 rpci->ops->release_pipe(inode);192192out:193193- up(&inode->i_sem);193193+ mutex_unlock(&inode->i_mutex);194194 return 0;195195}196196···202202 struct rpc_pipe_msg *msg;203203 int res = 0;204204205205- down(&inode->i_sem);205205+ mutex_lock(&inode->i_mutex);206206 if (rpci->ops == NULL) {207207 res = -EPIPE;208208 goto out_unlock;···229229 rpci->ops->destroy_msg(msg);230230 }231231out_unlock:232232- up(&inode->i_sem);232232+ mutex_unlock(&inode->i_mutex);233233 return res;234234}235235···240240 struct rpc_inode *rpci = RPC_I(inode);241241 int res;242242243243- down(&inode->i_sem);243243+ mutex_lock(&inode->i_mutex);244244 res = -EPIPE;245245 if (rpci->ops != NULL)246246 res = rpci->ops->downcall(filp, buf, len);247247- up(&inode->i_sem);247247+ mutex_unlock(&inode->i_mutex);248248 return res;249249}250250···322322323323 if (!ret) {324324 struct seq_file *m = file->private_data;325325- down(&inode->i_sem);325325+ mutex_lock(&inode->i_mutex);326326 clnt = RPC_I(inode)->private;327327 if (clnt) {328328 atomic_inc(&clnt->cl_users);···331331 single_release(inode, file);332332 ret = -EINVAL;333333 }334334- up(&inode->i_sem);334334+ mutex_unlock(&inode->i_mutex);335335 }336336 return ret;337337}···491491 struct dentry *dentry, *dvec[10];492492 int n = 0;493493494494- down(&dir->i_sem);494494+ mutex_lock(&dir->i_mutex);495495repeat:496496 spin_lock(&dcache_lock);497497 list_for_each_safe(pos, next, &parent->d_subdirs) {···519519 } while (n);520520 goto repeat;521521 }522522- up(&dir->i_sem);522522+ mutex_unlock(&dir->i_mutex);523523}524524525525static int···532532 struct dentry *dentry;533533 int mode, i;534534535535- down(&dir->i_sem);535535+ mutex_lock(&dir->i_mutex);536536 for (i = start; i < eof; i++) {537537 dentry = d_alloc_name(parent, files[i].name);538538 if (!dentry)···552552 dir->i_nlink++;553553 d_add(dentry, inode);554554 }555555- up(&dir->i_sem);555555+ mutex_unlock(&dir->i_mutex);556556 return 0;557557out_bad:558558- up(&dir->i_sem);558558+ mutex_unlock(&dir->i_mutex);559559 printk(KERN_WARNING "%s: %s failed to populate directory %s\n",560560 __FILE__, __FUNCTION__, parent->d_name.name);561561 return -ENOMEM;···609609 if ((error = rpc_lookup_parent(path, nd)) != 0)610610 return ERR_PTR(error);611611 dir = nd->dentry->d_inode;612612- down(&dir->i_sem);612612+ mutex_lock(&dir->i_mutex);613613 dentry = lookup_hash(nd);614614 if (IS_ERR(dentry))615615 goto out_err;···620620 }621621 return dentry;622622out_err:623623- up(&dir->i_sem);623623+ mutex_unlock(&dir->i_mutex);624624 rpc_release_path(nd);625625 return dentry;626626}···646646 if (error)647647 goto err_depopulate;648648out:649649- up(&dir->i_sem);649649+ mutex_unlock(&dir->i_mutex);650650 rpc_release_path(&nd);651651 return dentry;652652err_depopulate:···671671 if ((error = rpc_lookup_parent(path, &nd)) != 0)672672 return error;673673 dir = nd.dentry->d_inode;674674- down(&dir->i_sem);674674+ mutex_lock(&dir->i_mutex);675675 dentry = lookup_hash(&nd);676676 if (IS_ERR(dentry)) {677677 error = PTR_ERR(dentry);···681681 error = __rpc_rmdir(dir, dentry);682682 dput(dentry);683683out_release:684684- up(&dir->i_sem);684684+ mutex_unlock(&dir->i_mutex);685685 rpc_release_path(&nd);686686 return error;687687}···710710 rpci->ops = ops;711711 inode_dir_notify(dir, DN_CREATE);712712out:713713- up(&dir->i_sem);713713+ mutex_unlock(&dir->i_mutex);714714 rpc_release_path(&nd);715715 return dentry;716716err_dput:···732732 if ((error = rpc_lookup_parent(path, &nd)) != 0)733733 return error;734734 dir = nd.dentry->d_inode;735735- down(&dir->i_sem);735735+ mutex_lock(&dir->i_mutex);736736 dentry = lookup_hash(&nd);737737 if (IS_ERR(dentry)) {738738 error = PTR_ERR(dentry);···746746 dput(dentry);747747 inode_dir_notify(dir, DN_DELETE);748748out_release:749749- up(&dir->i_sem);749749+ mutex_unlock(&dir->i_mutex);750750 rpc_release_path(&nd);751751 return error;752752}