inode.h 5.45 KB
Newer Older
J. R. Okajima's avatar
J. R. Okajima committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Copyright (C) 2005-2019 Junjiro R. Okajima
 */

/*
 * inode operations
 */

#ifndef __AUFS_INODE_H__
#define __AUFS_INODE_H__

#ifdef __KERNEL__

#include <linux/fs.h>
J. R. Okajima's avatar
J. R. Okajima committed
16
#include "rwsem.h"
J. R. Okajima's avatar
J. R. Okajima committed
17
18
19
20
21

struct au_hinode {
	struct inode		*hi_inode;
};

J. R. Okajima's avatar
J. R. Okajima committed
22
23
24
25
26
struct au_iigen {
	spinlock_t	ig_spin;
	__u32		ig_generation;
};

J. R. Okajima's avatar
J. R. Okajima committed
27
struct au_iinfo {
J. R. Okajima's avatar
J. R. Okajima committed
28
29
30
	struct au_iigen		ii_generation;
	struct super_block	*ii_hsb1;	/* no get/put */

J. R. Okajima's avatar
J. R. Okajima committed
31
	struct au_rwsem		ii_rwsem;
J. R. Okajima's avatar
J. R. Okajima committed
32
	aufs_bindex_t		ii_btop, ii_bbot;
J. R. Okajima's avatar
J. R. Okajima committed
33
	__u32			ii_higen;
J. R. Okajima's avatar
J. R. Okajima committed
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
	struct au_hinode	*ii_hinode;
};

struct au_icntnr {
	struct au_iinfo		iinfo;
	struct inode		vfs_inode;
	struct rcu_head		rcu;
} ____cacheline_aligned_in_smp;

/* ---------------------------------------------------------------------- */

static inline struct au_iinfo *au_ii(struct inode *inode)
{
	BUG_ON(is_bad_inode(inode));
	return &(container_of(inode, struct au_icntnr, vfs_inode)->iinfo);
}

/* ---------------------------------------------------------------------- */

/* iinfo.c */
struct inode *au_h_iptr(struct inode *inode, aufs_bindex_t bindex);
void au_hiput(struct au_hinode *hinode);

void au_set_h_iptr(struct inode *inode, aufs_bindex_t bindex,
		   struct inode *h_inode, unsigned int flags);

J. R. Okajima's avatar
J. R. Okajima committed
60
61
void au_update_iigen(struct inode *inode, int half);

J. R. Okajima's avatar
J. R. Okajima committed
62
63
64
65
66
67
68
void au_icntnr_init_once(void *_c);
void au_hinode_init(struct au_hinode *hinode);
int au_iinfo_init(struct inode *inode);
void au_iinfo_fin(struct inode *inode);

/* ---------------------------------------------------------------------- */

J. R. Okajima's avatar
J. R. Okajima committed
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/* 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)

/* ---------------------------------------------------------------------- */

J. R. Okajima's avatar
J. R. Okajima committed
127
128
static inline void au_icntnr_init(struct au_icntnr *c)
{
J. R. Okajima's avatar
J. R. Okajima committed
129
130
131
#ifdef CONFIG_AUFS_DEBUG
	c->vfs_inode.i_mode = 0;
#endif
J. R. Okajima's avatar
J. R. Okajima committed
132
133
}

J. R. Okajima's avatar
J. R. Okajima committed
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
static inline unsigned int au_iigen(struct inode *inode)
{
	unsigned int gen;
	struct au_iinfo *iinfo;
	struct au_iigen *iigen;

	iinfo = au_ii(inode);
	iigen = &iinfo->ii_generation;
	spin_lock(&iigen->ig_spin);
	gen = iigen->ig_generation;
	spin_unlock(&iigen->ig_spin);

	return gen;
}

/* tiny test for inode number */
/* tmpfs generation is too rough */
static inline int au_test_higen(struct inode *inode, struct inode *h_inode)
{
	struct au_iinfo *iinfo;

	iinfo = au_ii(inode);
	AuRwMustAnyLock(&iinfo->ii_rwsem);
	return !(iinfo->ii_hsb1 == h_inode->i_sb
		 && iinfo->ii_higen == h_inode->i_generation);
}

static inline void au_iigen_dec(struct inode *inode)
{
	struct au_iinfo *iinfo;
	struct au_iigen *iigen;

	iinfo = au_ii(inode);
	iigen = &iinfo->ii_generation;
	spin_lock(&iigen->ig_spin);
	iigen->ig_generation--;
	spin_unlock(&iigen->ig_spin);
}

static inline int au_iigen_test(struct inode *inode, unsigned int sigen)
{
	int err;

	err = 0;
	if (unlikely(inode && au_iigen(inode) != sigen))
		err = -EIO;

	return err;
}

J. R. Okajima's avatar
J. R. Okajima committed
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
/* ---------------------------------------------------------------------- */

static inline struct au_hinode *au_hinode(struct au_iinfo *iinfo,
					  aufs_bindex_t bindex)
{
	return iinfo->ii_hinode + bindex;
}

static inline int au_is_bad_inode(struct inode *inode)
{
	return !!(is_bad_inode(inode) || !au_hinode(au_ii(inode), 0));
}

static inline aufs_bindex_t au_ibtop(struct inode *inode)
{
J. R. Okajima's avatar
J. R. Okajima committed
199
	IiMustAnyLock(inode);
J. R. Okajima's avatar
J. R. Okajima committed
200
201
202
203
204
	return au_ii(inode)->ii_btop;
}

static inline aufs_bindex_t au_ibbot(struct inode *inode)
{
J. R. Okajima's avatar
J. R. Okajima committed
205
	IiMustAnyLock(inode);
J. R. Okajima's avatar
J. R. Okajima committed
206
207
208
209
210
	return au_ii(inode)->ii_bbot;
}

static inline void au_set_ibtop(struct inode *inode, aufs_bindex_t bindex)
{
J. R. Okajima's avatar
J. R. Okajima committed
211
	IiMustWriteLock(inode);
J. R. Okajima's avatar
J. R. Okajima committed
212
213
214
215
216
	au_ii(inode)->ii_btop = bindex;
}

static inline void au_set_ibbot(struct inode *inode, aufs_bindex_t bindex)
{
J. R. Okajima's avatar
J. R. Okajima committed
217
	IiMustWriteLock(inode);
J. R. Okajima's avatar
J. R. Okajima committed
218
219
220
221
222
	au_ii(inode)->ii_bbot = bindex;
}

static inline struct au_hinode *au_hi(struct inode *inode, aufs_bindex_t bindex)
{
J. R. Okajima's avatar
J. R. Okajima committed
223
	IiMustAnyLock(inode);
J. R. Okajima's avatar
J. R. Okajima committed
224
225
226
227
228
	return au_hinode(au_ii(inode), bindex);
}

#endif /* __KERNEL__ */
#endif /* __AUFS_INODE_H__ */