cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

lock.c (2685B)


      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 */
     22void 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
     35void 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
     52int __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
     70void 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 */
     87void 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
     95void 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