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 ...@@ -43,4 +43,10 @@ config AUFS_BRANCH_MAX_32767
in a single aufs. The larger value consumes more system in a single aufs. The larger value consumes more system
resources and has a minor impact to performance. resources and has a minor impact to performance.
endchoice 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 endif
...@@ -12,8 +12,11 @@ ...@@ -12,8 +12,11 @@
#ifdef __KERNEL__ #ifdef __KERNEL__
#include "debug.h"
#include "inode.h" #include "inode.h"
#include "module.h" #include "module.h"
#include "rwsem.h"
#include "super.h" #include "super.h"
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
......
...@@ -14,6 +14,8 @@ struct inode *au_h_iptr(struct inode *inode, aufs_bindex_t bindex) ...@@ -14,6 +14,8 @@ struct inode *au_h_iptr(struct inode *inode, aufs_bindex_t bindex)
struct inode *h_inode; struct inode *h_inode;
struct au_hinode *hinode; struct au_hinode *hinode;
IiMustAnyLock(inode);
hinode = au_hinode(au_ii(inode), bindex); hinode = au_hinode(au_ii(inode), bindex);
h_inode = hinode->hi_inode; h_inode = hinode->hi_inode;
AuDebugOn(h_inode && atomic_read(&h_inode->i_count) <= 0); 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, ...@@ -33,6 +35,8 @@ void au_set_h_iptr(struct inode *inode, aufs_bindex_t bindex,
struct inode *hi; struct inode *hi;
struct au_iinfo *iinfo = au_ii(inode); struct au_iinfo *iinfo = au_ii(inode);
IiMustWriteLock(inode);
hinode = au_hinode(iinfo, bindex); hinode = au_hinode(iinfo, bindex);
hi = hinode->hi_inode; hi = hinode->hi_inode;
AuDebugOn(h_inode && atomic_read(&h_inode->i_count) <= 0); AuDebugOn(h_inode && atomic_read(&h_inode->i_count) <= 0);
...@@ -55,8 +59,7 @@ void au_icntnr_init_once(void *_c) ...@@ -55,8 +59,7 @@ void au_icntnr_init_once(void *_c)
struct au_icntnr *c = _c; struct au_icntnr *c = _c;
struct au_iinfo *iinfo = &c->iinfo; struct au_iinfo *iinfo = &c->iinfo;
init_rwsem(&iinfo->ii_rwsem); au_rw_init(&iinfo->ii_rwsem);
down_write(&iinfo->ii_rwsem);
inode_init_once(&c->vfs_inode); inode_init_once(&c->vfs_inode);
} }
...@@ -108,4 +111,5 @@ void au_iinfo_fin(struct inode *inode) ...@@ -108,4 +111,5 @@ void au_iinfo_fin(struct inode *inode)
} }
} }
au_kfree_small(iinfo->ii_hinode); au_kfree_small(iinfo->ii_hinode);
AuRwDestroy(&iinfo->ii_rwsem);
} }
...@@ -13,13 +13,14 @@ ...@@ -13,13 +13,14 @@
#ifdef __KERNEL__ #ifdef __KERNEL__
#include <linux/fs.h> #include <linux/fs.h>
#include "rwsem.h"
struct au_hinode { struct au_hinode {
struct inode *hi_inode; struct inode *hi_inode;
}; };
struct au_iinfo { struct au_iinfo {
struct rw_semaphore ii_rwsem; struct au_rwsem ii_rwsem;
aufs_bindex_t ii_btop, ii_bbot; aufs_bindex_t ii_btop, ii_bbot;
struct au_hinode *ii_hinode; struct au_hinode *ii_hinode;
}; };
...@@ -54,6 +55,64 @@ void au_iinfo_fin(struct inode *inode); ...@@ -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) static inline void au_icntnr_init(struct au_icntnr *c)
{ {
/* re-commit later */ /* re-commit later */
...@@ -74,26 +133,31 @@ static inline int au_is_bad_inode(struct inode *inode) ...@@ -74,26 +133,31 @@ static inline int au_is_bad_inode(struct inode *inode)
static inline aufs_bindex_t au_ibtop(struct inode *inode) static inline aufs_bindex_t au_ibtop(struct inode *inode)
{ {
IiMustAnyLock(inode);
return au_ii(inode)->ii_btop; return au_ii(inode)->ii_btop;
} }
static inline aufs_bindex_t au_ibbot(struct inode *inode) static inline aufs_bindex_t au_ibbot(struct inode *inode)
{ {
IiMustAnyLock(inode);
return au_ii(inode)->ii_bbot; return au_ii(inode)->ii_bbot;
} }
static inline void au_set_ibtop(struct inode *inode, aufs_bindex_t bindex) static inline void au_set_ibtop(struct inode *inode, aufs_bindex_t bindex)
{ {
IiMustWriteLock(inode);
au_ii(inode)->ii_btop = bindex; au_ii(inode)->ii_btop = bindex;
} }
static inline void au_set_ibbot(struct inode *inode, aufs_bindex_t bindex) static inline void au_set_ibbot(struct inode *inode, aufs_bindex_t bindex)
{ {
IiMustWriteLock(inode);
au_ii(inode)->ii_bbot = bindex; au_ii(inode)->ii_bbot = bindex;
} }
static inline struct au_hinode *au_hi(struct inode *inode, aufs_bindex_t bindex) static inline struct au_hinode *au_hi(struct inode *inode, aufs_bindex_t bindex)
{ {
IiMustAnyLock(inode);
return au_hinode(au_ii(inode), bindex); 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