brintos

brintos / linux-shallow public Read only

0
0
Text · 2.6 KiB · 46bd7bd Raw
102 lines · c
1// SPDX-License-Identifier: GPL-2.02#include "reiserfs.h"3#include <linux/mutex.h>4 5/*6 * The previous reiserfs locking scheme was heavily based on7 * the tricky properties of the Bkl:8 *9 * - it was acquired recursively by a same task10 * - the performances relied on the release-while-schedule() property11 *12 * Now that we replace it by a mutex, we still want to keep the same13 * recursive property to avoid big changes in the code structure.14 * We use our own lock_owner here because the owner field on a mutex15 * is only available in SMP or mutex debugging, also we only need this field16 * 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 because19 * 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 want42	 * 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 superblock85 * 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_CHECK95void 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#endif102