root/fs/reiserfs/lock.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. reiserfs_write_lock
  2. reiserfs_write_unlock
  3. reiserfs_write_unlock_nested
  4. reiserfs_write_lock_nested
  5. reiserfs_check_lock_depth
  6. reiserfs_lock_check_recursive

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

/* [<][>][^][v][top][bottom][index][help] */