Blame view
fs/reiserfs/lock.c
2.59 KB
f466c6fdb
|
1 |
#include "reiserfs.h" |
8ebc42323
|
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
#include <linux/mutex.h> /* * The previous reiserfs locking scheme was heavily based on * the tricky properties of the Bkl: * * - it was acquired recursively by a same task * - the performances relied on the release-while-schedule() property * * Now that we replace it by a mutex, we still want to keep the same * recursive property to avoid big changes in the code structure. * We use our own lock_owner here because the owner field on a mutex * is only available in SMP or mutex debugging, also we only need this field * for this mutex, no need for a system wide mutex facility. * * Also this lock is often released before a call that could block because |
25985edce
|
18 |
* reiserfs performances were partially based on the release while schedule() |
8ebc42323
|
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
* property of the Bkl. */ void reiserfs_write_lock(struct super_block *s) { struct reiserfs_sb_info *sb_i = REISERFS_SB(s); if (sb_i->lock_owner != current) { mutex_lock(&sb_i->lock); sb_i->lock_owner = current; } /* No need to protect it, only the current task touches it */ sb_i->lock_depth++; } void reiserfs_write_unlock(struct super_block *s) { struct reiserfs_sb_info *sb_i = REISERFS_SB(s); /* * Are we unlocking without even holding the lock? |
805031859
|
40 41 |
* Such a situation must raise a BUG() if we don't want * to corrupt the data. |
8ebc42323
|
42 |
*/ |
805031859
|
43 |
BUG_ON(sb_i->lock_owner != current); |
8ebc42323
|
44 45 46 47 48 49 |
if (--sb_i->lock_depth == -1) { sb_i->lock_owner = NULL; mutex_unlock(&sb_i->lock); } } |
278f6679f
|
50 |
int __must_check reiserfs_write_unlock_nested(struct super_block *s) |
daf88c898
|
51 52 |
{ struct reiserfs_sb_info *sb_i = REISERFS_SB(s); |
278f6679f
|
53 |
int depth; |
daf88c898
|
54 |
|
278f6679f
|
55 56 57 58 59 60 61 62 63 |
/* this can happen when the lock isn't always held */ if (sb_i->lock_owner != current) return -1; depth = sb_i->lock_depth; sb_i->lock_depth = -1; sb_i->lock_owner = NULL; mutex_unlock(&sb_i->lock); |
daf88c898
|
64 |
|
278f6679f
|
65 |
return depth; |
daf88c898
|
66 |
} |
278f6679f
|
67 |
void reiserfs_write_lock_nested(struct super_block *s, int depth) |
daf88c898
|
68 |
{ |
278f6679f
|
69 70 71 72 73 74 75 76 77 |
struct reiserfs_sb_info *sb_i = REISERFS_SB(s); /* this can happen when the lock isn't always held */ if (depth == -1) return; mutex_lock(&sb_i->lock); sb_i->lock_owner = current; sb_i->lock_depth = depth; |
daf88c898
|
78 79 80 |
} /* |
8ebc42323
|
81 82 83 84 85 86 |
* Utility function to force a BUG if it is called without the superblock * write lock held. caller is the string printed just before calling BUG() */ void reiserfs_check_lock_depth(struct super_block *sb, char *caller) { struct reiserfs_sb_info *sb_i = REISERFS_SB(sb); |
278f6679f
|
87 |
WARN_ON(sb_i->lock_depth < 0); |
8ebc42323
|
88 |
} |
c4a62ca36
|
89 90 91 92 93 94 95 96 97 98 |
#ifdef CONFIG_REISERFS_CHECK void reiserfs_lock_check_recursive(struct super_block *sb) { struct reiserfs_sb_info *sb_i = REISERFS_SB(sb); WARN_ONCE((sb_i->lock_depth > 0), "Unwanted recursive reiserfs lock! "); } #endif |