Commit c74884be authored by J. R. Okajima's avatar J. R. Okajima
Browse files

aufs: iinfo, debug by rwsem



This is a very old debugging routine for rw_semaphore I was using
privately and less meaningful to other people. It was (probably) before
LOCKDEP feature was introduced, but now it is based upon LOCKDEP. This
is compiled when CONFIG_AUFS_DEBUG is enabled.
Signed-off-by: default avatarJ. R. Okajima <hooanon05g@gmail.com>
parent a3d2caf2
......@@ -43,4 +43,10 @@ config AUFS_BRANCH_MAX_32767
in a single aufs. The larger value consumes more system
resources and has a minor impact to performance.
endchoice
config AUFS_DEBUG
bool "Debug aufs"
help
Enable this to compile aufs internal debug code.
It will have a negative impact to the performance.
endif
......@@ -12,8 +12,11 @@
#ifdef __KERNEL__
#include "debug.h"
#include "inode.h"
#include "module.h"
#include "rwsem.h"
#include "super.h"
#endif /* __KERNEL__ */
......
......@@ -14,6 +14,8 @@ struct inode *au_h_iptr(struct inode *inode, aufs_bindex_t bindex)
struct inode *h_inode;
struct au_hinode *hinode;
IiMustAnyLock(inode);
hinode = au_hinode(au_ii(inode), bindex);
h_inode = hinode->hi_inode;
AuDebugOn(h_inode && atomic_read(&h_inode->i_count) <= 0);
......@@ -33,6 +35,8 @@ void au_set_h_iptr(struct inode *inode, aufs_bindex_t bindex,
struct inode *hi;
struct au_iinfo *iinfo = au_ii(inode);
IiMustWriteLock(inode);
hinode = au_hinode(iinfo, bindex);
hi = hinode->hi_inode;
AuDebugOn(h_inode && atomic_read(&h_inode->i_count) <= 0);
......@@ -55,8 +59,7 @@ void au_icntnr_init_once(void *_c)
struct au_icntnr *c = _c;
struct au_iinfo *iinfo = &c->iinfo;
init_rwsem(&iinfo->ii_rwsem);
down_write(&iinfo->ii_rwsem);
au_rw_init(&iinfo->ii_rwsem);
inode_init_once(&c->vfs_inode);
}
......@@ -108,4 +111,5 @@ void au_iinfo_fin(struct inode *inode)
}
}
au_kfree_small(iinfo->ii_hinode);
AuRwDestroy(&iinfo->ii_rwsem);
}
......@@ -13,13 +13,14 @@
#ifdef __KERNEL__
#include <linux/fs.h>
#include "rwsem.h"
struct au_hinode {
struct inode *hi_inode;
};
struct au_iinfo {
struct rw_semaphore ii_rwsem;
struct au_rwsem ii_rwsem;
aufs_bindex_t ii_btop, ii_bbot;
struct au_hinode *ii_hinode;
};
......@@ -54,6 +55,64 @@ void au_iinfo_fin(struct inode *inode);
/* ---------------------------------------------------------------------- */
/* lock subclass for iinfo */
enum {
AuLsc_II_CHILD, /* child first */
AuLsc_II_CHILD2, /* rename(2), link(2), and cpup at hnotify */
AuLsc_II_CHILD3, /* copyup dirs */
AuLsc_II_PARENT, /* see AuLsc_I_PARENT in vfsub.h */
AuLsc_II_PARENT2,
AuLsc_II_PARENT3, /* copyup dirs */
AuLsc_II_NEW_CHILD
};
/*
* ii_read_lock_child, ii_write_lock_child,
* ii_read_lock_child2, ii_write_lock_child2,
* ii_read_lock_child3, ii_write_lock_child3,
* ii_read_lock_parent, ii_write_lock_parent,
* ii_read_lock_parent2, ii_write_lock_parent2,
* ii_read_lock_parent3, ii_write_lock_parent3,
* ii_read_lock_new_child, ii_write_lock_new_child,
*/
#define AuReadLockFunc(name, lsc) \
static inline void ii_read_lock_##name(struct inode *i) \
{ \
au_rw_read_lock_nested(&au_ii(i)->ii_rwsem, AuLsc_II_##lsc); \
}
#define AuWriteLockFunc(name, lsc) \
static inline void ii_write_lock_##name(struct inode *i) \
{ \
au_rw_write_lock_nested(&au_ii(i)->ii_rwsem, AuLsc_II_##lsc); \
}
#define AuRWLockFuncs(name, lsc) \
AuReadLockFunc(name, lsc) \
AuWriteLockFunc(name, lsc)
AuRWLockFuncs(child, CHILD);
AuRWLockFuncs(child2, CHILD2);
AuRWLockFuncs(child3, CHILD3);
AuRWLockFuncs(parent, PARENT);
AuRWLockFuncs(parent2, PARENT2);
AuRWLockFuncs(parent3, PARENT3);
AuRWLockFuncs(new_child, NEW_CHILD);
#undef AuReadLockFunc
#undef AuWriteLockFunc
#undef AuRWLockFuncs
#define ii_read_unlock(i) au_rw_read_unlock(&au_ii(i)->ii_rwsem)
#define ii_write_unlock(i) au_rw_write_unlock(&au_ii(i)->ii_rwsem)
#define ii_downgrade_lock(i) au_rw_dgrade_lock(&au_ii(i)->ii_rwsem)
#define IiMustNoWaiters(i) AuRwMustNoWaiters(&au_ii(i)->ii_rwsem)
#define IiMustAnyLock(i) AuRwMustAnyLock(&au_ii(i)->ii_rwsem)
#define IiMustWriteLock(i) AuRwMustWriteLock(&au_ii(i)->ii_rwsem)
/* ---------------------------------------------------------------------- */
static inline void au_icntnr_init(struct au_icntnr *c)
{
/* re-commit later */
......@@ -74,26 +133,31 @@ static inline int au_is_bad_inode(struct inode *inode)
static inline aufs_bindex_t au_ibtop(struct inode *inode)
{
IiMustAnyLock(inode);
return au_ii(inode)->ii_btop;
}
static inline aufs_bindex_t au_ibbot(struct inode *inode)
{
IiMustAnyLock(inode);
return au_ii(inode)->ii_bbot;
}
static inline void au_set_ibtop(struct inode *inode, aufs_bindex_t bindex)
{
IiMustWriteLock(inode);
au_ii(inode)->ii_btop = bindex;
}
static inline void au_set_ibbot(struct inode *inode, aufs_bindex_t bindex)
{
IiMustWriteLock(inode);
au_ii(inode)->ii_bbot = bindex;
}
static inline struct au_hinode *au_hi(struct inode *inode, aufs_bindex_t bindex)
{
IiMustAnyLock(inode);
return au_hinode(au_ii(inode), bindex);
}
......
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2005-2019 Junjiro R. Okajima
*/
/*
* simple read-write semaphore wrappers
*/
#ifndef __AUFS_RWSEM_H__
#define __AUFS_RWSEM_H__
#ifdef __KERNEL__
#include "debug.h"
/* in the future, the name 'au_rwsem' will be totally gone */
#define au_rwsem rw_semaphore
/* to debug easier, do not make them inlined functions */
#define AuRwMustNoWaiters(rw) AuDebugOn(rwsem_is_contended(rw))
/* rwsem_is_locked() is unusable */
#define AuRwMustReadLock(rw) AuDebugOn(!lockdep_recursing(current) \
&& debug_locks \
&& !lockdep_is_held_type(rw, 1))
#define AuRwMustWriteLock(rw) AuDebugOn(!lockdep_recursing(current) \
&& debug_locks \
&& !lockdep_is_held_type(rw, 0))
#define AuRwMustAnyLock(rw) AuDebugOn(!lockdep_recursing(current) \
&& debug_locks \
&& !lockdep_is_held(rw))
#define AuRwDestroy(rw) AuDebugOn(!lockdep_recursing(current) \
&& debug_locks \
&& lockdep_is_held(rw))
#define au_rw_init(rw) init_rwsem(rw)
#define au_rw_init_wlock(rw) do { \
au_rw_init(rw); \
down_write(rw); \
} while (0)
#define au_rw_init_wlock_nested(rw, lsc) do { \
au_rw_init(rw); \
down_write_nested(rw, lsc); \
} while (0)
#define au_rw_read_lock(rw) down_read(rw)
#define au_rw_read_lock_nested(rw, lsc) down_read_nested(rw, lsc)
#define au_rw_read_unlock(rw) up_read(rw)
#define au_rw_dgrade_lock(rw) downgrade_write(rw)
#define au_rw_write_lock(rw) down_write(rw)
#define au_rw_write_lock_nested(rw, lsc) down_write_nested(rw, lsc)
#define au_rw_write_unlock(rw) up_write(rw)
/* why is not _nested version defined? */
#define au_rw_read_trylock(rw) down_read_trylock(rw)
#define au_rw_write_trylock(rw) down_write_trylock(rw)
#endif /* __KERNEL__ */
#endif /* __AUFS_RWSEM_H__ */
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment