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