2
* Copyright (C) 2005-2008 Junjiro Okajima
4
* This program, aufs is free software; you can redistribute it and/or modify
5
* it under the terms of the GNU General Public License as published by
6
* the Free Software Foundation; either version 2 of the License, or
7
* (at your option) any later version.
9
* This program is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* GNU General Public License for more details.
14
* You should have received a copy of the GNU General Public License
15
* along with this program; if not, write to the Free Software
16
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20
* $Id: misc.h,v 1.2 2008/04/21 01:33:00 sfjro Exp $
23
#ifndef __AUFS_MISC_H__
24
#define __AUFS_MISC_H__
29
#include <linux/namei.h>
30
#include <linux/aufs_type.h>
32
/* ---------------------------------------------------------------------- */
34
typedef unsigned int au_gen_t;
35
/* see linux/include/linux/jiffies.h */
36
#define AuGenYounger(a, b) ((int)(b) - (int)(a) < 0)
37
#define AuGenOlder(a, b) AufsGenYounger(b, a)
39
/* ---------------------------------------------------------------------- */
42
struct rw_semaphore rwsem;
43
#ifdef CONFIG_AUFS_DEBUG
48
#ifdef CONFIG_AUFS_DEBUG
49
#define AuDbgRcntInit(rw) do { \
50
atomic_set(&(rw)->rcnt, 0); \
54
#define AuDbgRcntInc(rw) atomic_inc_return(&(rw)->rcnt)
55
#define AuDbgRcntDec(rw) WARN_ON(atomic_dec_return(&(rw)->rcnt) < 0)
57
#define AuDbgRcntInit(rw) do {} while (0)
58
#define AuDbgRcntInc(rw) do {} while (0)
59
#define AuDbgRcntDec(rw) do {} while (0)
60
#endif /* CONFIG_AUFS_DEBUG */
62
static inline void au_rw_init_nolock(struct au_rwsem *rw)
65
init_rwsem(&rw->rwsem);
68
static inline void au_rw_init_wlock(struct au_rwsem *rw)
70
au_rw_init_nolock(rw);
71
down_write(&rw->rwsem);
74
static inline void au_rw_init_wlock_nested(struct au_rwsem *rw,
77
au_rw_init_nolock(rw);
78
down_write_nested(&rw->rwsem, lsc);
81
static inline void au_rw_read_lock(struct au_rwsem *rw)
83
down_read(&rw->rwsem);
87
static inline void au_rw_read_lock_nested(struct au_rwsem *rw, unsigned int lsc)
89
down_read_nested(&rw->rwsem, lsc);
93
static inline void au_rw_read_unlock(struct au_rwsem *rw)
99
static inline void au_rw_dgrade_lock(struct au_rwsem *rw)
102
downgrade_write(&rw->rwsem);
105
static inline void au_rw_write_lock(struct au_rwsem *rw)
107
down_write(&rw->rwsem);
110
static inline void au_rw_write_lock_nested(struct au_rwsem *rw,
113
down_write_nested(&rw->rwsem, lsc);
116
static inline void au_rw_write_unlock(struct au_rwsem *rw)
118
up_write(&rw->rwsem);
121
/* why is not _nested version defined */
122
static inline int au_rw_read_trylock(struct au_rwsem *rw)
124
int ret = down_read_trylock(&rw->rwsem);
130
static inline int au_rw_write_trylock(struct au_rwsem *rw)
132
return down_write_trylock(&rw->rwsem);
139
/* to debug easier, do not make them inlined functions */
140
#define AuRwMustNoWaiters(rw) AuDebugOn(!list_empty(&(rw)->rwsem.wait_list))
141
#define AuRwMustAnyLock(rw) AuDebugOn(down_write_trylock(&(rw)->rwsem))
142
#ifdef CONFIG_AUFS_DEBUG
143
#define AuRwMustReadLock(rw) do { \
144
AuRwMustAnyLock(rw); \
145
AuDebugOn(!atomic_read(&(rw)->rcnt)); \
148
#define AuRwMustWriteLock(rw) do { \
149
AuRwMustAnyLock(rw); \
150
AuDebugOn(atomic_read(&(rw)->rcnt)); \
153
#define AuRwMustReadLock(rw) AuRwMustAnyLock(rw)
154
#define AuRwMustWriteLock(rw) AuRwMustAnyLock(rw)
155
#endif /* CONFIG_AUFS_DEBUG */
157
#define AuSimpleLockRwsemFuncs(prefix, param, rwsem) \
158
static inline void prefix##_read_lock(param) \
159
{ au_rw_read_lock(&(rwsem)); } \
160
static inline void prefix##_write_lock(param) \
161
{ au_rw_write_lock(&(rwsem)); } \
162
static inline int prefix##_read_trylock(param) \
163
{ return au_rw_read_trylock(&(rwsem)); } \
164
static inline int prefix##_write_trylock(param) \
165
{ return au_rw_write_trylock(&(rwsem)); }
166
//static inline void prefix##_read_trylock_nested(param, lsc)
167
//{au_rw_read_trylock_nested(&(rwsem, lsc));}
168
//static inline void prefix##_write_trylock_nestd(param, lsc)
169
//{au_rw_write_trylock_nested(&(rwsem), nested);}
171
#define AuSimpleUnlockRwsemFuncs(prefix, param, rwsem) \
172
static inline void prefix##_read_unlock(param) \
173
{ au_rw_read_unlock(&(rwsem)); } \
174
static inline void prefix##_write_unlock(param) \
175
{ au_rw_write_unlock(&(rwsem)); } \
176
static inline void prefix##_downgrade_lock(param) \
177
{ au_rw_dgrade_lock(&(rwsem)); }
179
#define AuSimpleRwsemFuncs(prefix, param, rwsem) \
180
AuSimpleLockRwsemFuncs(prefix, param, rwsem) \
181
AuSimpleUnlockRwsemFuncs(prefix, param, rwsem)
183
/* ---------------------------------------------------------------------- */
185
void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp);
188
struct nameidata *au_dup_nd(struct au_sbinfo *sbinfo, struct nameidata *dst,
189
struct nameidata *src);
191
struct nameidata *au_fake_dm(struct nameidata *fake_nd, struct nameidata *nd,
192
struct super_block *sb, aufs_bindex_t bindex);
193
void au_fake_dm_release(struct nameidata *fake_nd);
194
int au_h_create(struct inode *h_dir, struct dentry *h_dentry, int mode,
195
int dlgt, struct nameidata *nd, struct vfsmount *nfsmnt);
197
int au_copy_file(struct file *dst, struct file *src, loff_t len,
198
struct super_block *sb);
200
#endif /* __KERNEL__ */
201
#endif /* __AUFS_MISC_H__ */