1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
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
60
61
62
63
64
65
66
67
68
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
|
/*
* Copyright (C) 2005-2008 Junjiro Okajima
*
* This program, aufs is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
* directory operations
*
* $Id: dir.h,v 1.26 2008/03/31 07:45:32 sfjro Exp $
*/
#ifndef __AUFS_DIR_H__
#define __AUFS_DIR_H__
#ifdef __KERNEL__
#include <linux/fs.h>
#include <linux/version.h>
#include <linux/aufs_type.h>
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
typedef u64 au_filldir_ino_t;
#else
typedef ino_t au_filldir_ino_t;
#endif
/* ---------------------------------------------------------------------- */
/* need to be faster and smaller */
#define AuSize_DEBLK 512 // todo: changeable
#define AuSize_NHASH 32 // todo: changeable
#if AuSize_DEBLK < NAME_MAX || PAGE_SIZE < AuSize_DEBLK
#error invalid size AuSize_DEBLK
#endif
typedef char aufs_deblk_t[AuSize_DEBLK];
struct aufs_nhash {
struct hlist_head heads[AuSize_NHASH];
};
struct aufs_destr {
unsigned char len;
char name[0];
} __packed;
struct aufs_dehstr {
struct hlist_node hash;
struct aufs_destr *str;
};
struct aufs_de {
ino_t de_ino;
unsigned char de_type;
/* caution: packed */
struct aufs_destr de_str;
} __packed;
struct aufs_wh {
struct hlist_node wh_hash;
aufs_bindex_t wh_bindex;
#ifdef CONFIG_AUFS_SHWH
ino_t wh_ino;
unsigned char wh_type;
/* caution: packed */
#endif
struct aufs_destr wh_str;
} __packed;
union aufs_deblk_p {
unsigned char *p;
aufs_deblk_t *deblk;
struct aufs_de *de;
};
struct aufs_vdir {
aufs_deblk_t **vd_deblk;
int vd_nblk;
struct {
int i;
union aufs_deblk_p p;
} vd_last;
unsigned long vd_version;
unsigned long vd_jiffy;
};
/* ---------------------------------------------------------------------- */
/* dir.c */
extern struct file_operations aufs_dir_fop;
int au_test_empty_lower(struct dentry *dentry);
int au_test_empty(struct dentry *dentry, struct aufs_nhash *whlist);
void au_add_nlink(struct inode *dir, struct inode *h_dir);
void au_sub_nlink(struct inode *dir, struct inode *h_dir);
/* vdir.c */
struct aufs_nhash *nhash_new(gfp_t gfp);
void nhash_del(struct aufs_nhash *nhash);
void nhash_init(struct aufs_nhash *nhash);
void nhash_move(struct aufs_nhash *dst, struct aufs_nhash *src);
void nhash_fin(struct aufs_nhash *nhash);
int nhash_test_longer_wh(struct aufs_nhash *whlist, aufs_bindex_t btgt,
int limit);
int nhash_test_known_wh(struct aufs_nhash *whlist, char *name, int namelen);
int nhash_append_wh(struct aufs_nhash *whlist, char *name, int namelen,
ino_t ino, unsigned int d_type, aufs_bindex_t bindex,
unsigned char shwh);
void au_vdir_free(struct aufs_vdir *vdir);
int au_vdir_init(struct file *file);
int au_fill_de(struct file *file, void *dirent, filldir_t filldir);
/* ---------------------------------------------------------------------- */
static inline
unsigned int au_name_hash(const unsigned char *name, unsigned int len)
{
return (full_name_hash(name, len) % AuSize_NHASH);
}
static inline
void au_shwh_init_wh(struct aufs_wh *wh, ino_t ino, unsigned char d_type)
{
#ifdef CONFIG_AUFS_SHWH
wh->wh_ino = ino;
wh->wh_type = d_type;
#endif
}
#endif /* __KERNEL__ */
#endif /* __AUFS_DIR_H__ */
|