]>
Commit | Line | Data |
---|---|---|
c088e31d SF |
1 | /* |
2 | * Copyright (C) 2005-2017 Junjiro R. Okajima | |
3 | * | |
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. | |
8 | * | |
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. | |
13 | * | |
14 | * You should have received a copy of the GNU General Public License | |
15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
16 | */ | |
17 | ||
18 | /* | |
19 | * inode private data | |
20 | */ | |
21 | ||
22 | #include "aufs.h" | |
23 | ||
24 | struct inode *au_h_iptr(struct inode *inode, aufs_bindex_t bindex) | |
25 | { | |
26 | struct inode *h_inode; | |
27 | struct au_hinode *hinode; | |
28 | ||
29 | IiMustAnyLock(inode); | |
30 | ||
31 | hinode = au_hinode(au_ii(inode), bindex); | |
32 | h_inode = hinode->hi_inode; | |
33 | AuDebugOn(h_inode && atomic_read(&h_inode->i_count) <= 0); | |
34 | return h_inode; | |
35 | } | |
36 | ||
37 | /* todo: hard/soft set? */ | |
38 | void au_hiput(struct au_hinode *hinode) | |
39 | { | |
40 | au_hn_free(hinode); | |
41 | dput(hinode->hi_whdentry); | |
42 | iput(hinode->hi_inode); | |
43 | } | |
44 | ||
45 | unsigned int au_hi_flags(struct inode *inode, int isdir) | |
46 | { | |
47 | unsigned int flags; | |
48 | const unsigned int mnt_flags = au_mntflags(inode->i_sb); | |
49 | ||
50 | flags = 0; | |
51 | if (au_opt_test(mnt_flags, XINO)) | |
52 | au_fset_hi(flags, XINO); | |
53 | if (isdir && au_opt_test(mnt_flags, UDBA_HNOTIFY)) | |
54 | au_fset_hi(flags, HNOTIFY); | |
55 | return flags; | |
56 | } | |
57 | ||
58 | void au_set_h_iptr(struct inode *inode, aufs_bindex_t bindex, | |
59 | struct inode *h_inode, unsigned int flags) | |
60 | { | |
61 | struct au_hinode *hinode; | |
62 | struct inode *hi; | |
63 | struct au_iinfo *iinfo = au_ii(inode); | |
64 | ||
65 | IiMustWriteLock(inode); | |
66 | ||
67 | hinode = au_hinode(iinfo, bindex); | |
68 | hi = hinode->hi_inode; | |
69 | AuDebugOn(h_inode && atomic_read(&h_inode->i_count) <= 0); | |
70 | ||
71 | if (hi) | |
72 | au_hiput(hinode); | |
73 | hinode->hi_inode = h_inode; | |
74 | if (h_inode) { | |
75 | int err; | |
76 | struct super_block *sb = inode->i_sb; | |
77 | struct au_branch *br; | |
78 | ||
79 | AuDebugOn(inode->i_mode | |
80 | && (h_inode->i_mode & S_IFMT) | |
81 | != (inode->i_mode & S_IFMT)); | |
82 | if (bindex == iinfo->ii_btop) | |
83 | au_cpup_igen(inode, h_inode); | |
84 | br = au_sbr(sb, bindex); | |
85 | hinode->hi_id = br->br_id; | |
86 | if (au_ftest_hi(flags, XINO)) { | |
87 | err = au_xino_write(sb, bindex, h_inode->i_ino, | |
88 | inode->i_ino); | |
89 | if (unlikely(err)) | |
90 | AuIOErr1("failed au_xino_write() %d\n", err); | |
91 | } | |
92 | ||
93 | if (au_ftest_hi(flags, HNOTIFY) | |
94 | && au_br_hnotifyable(br->br_perm)) { | |
95 | err = au_hn_alloc(hinode, inode); | |
96 | if (unlikely(err)) | |
97 | AuIOErr1("au_hn_alloc() %d\n", err); | |
98 | } | |
99 | } | |
100 | } | |
101 | ||
102 | void au_set_hi_wh(struct inode *inode, aufs_bindex_t bindex, | |
103 | struct dentry *h_wh) | |
104 | { | |
105 | struct au_hinode *hinode; | |
106 | ||
107 | IiMustWriteLock(inode); | |
108 | ||
109 | hinode = au_hinode(au_ii(inode), bindex); | |
110 | AuDebugOn(hinode->hi_whdentry); | |
111 | hinode->hi_whdentry = h_wh; | |
112 | } | |
113 | ||
114 | void au_update_iigen(struct inode *inode, int half) | |
115 | { | |
116 | struct au_iinfo *iinfo; | |
117 | struct au_iigen *iigen; | |
118 | unsigned int sigen; | |
119 | ||
120 | sigen = au_sigen(inode->i_sb); | |
121 | iinfo = au_ii(inode); | |
122 | iigen = &iinfo->ii_generation; | |
123 | spin_lock(&iigen->ig_spin); | |
124 | iigen->ig_generation = sigen; | |
125 | if (half) | |
126 | au_ig_fset(iigen->ig_flags, HALF_REFRESHED); | |
127 | else | |
128 | au_ig_fclr(iigen->ig_flags, HALF_REFRESHED); | |
129 | spin_unlock(&iigen->ig_spin); | |
130 | } | |
131 | ||
132 | /* it may be called at remount time, too */ | |
133 | void au_update_ibrange(struct inode *inode, int do_put_zero) | |
134 | { | |
135 | struct au_iinfo *iinfo; | |
136 | aufs_bindex_t bindex, bbot; | |
137 | ||
138 | AuDebugOn(au_is_bad_inode(inode)); | |
139 | IiMustWriteLock(inode); | |
140 | ||
141 | iinfo = au_ii(inode); | |
142 | if (do_put_zero && iinfo->ii_btop >= 0) { | |
143 | for (bindex = iinfo->ii_btop; bindex <= iinfo->ii_bbot; | |
144 | bindex++) { | |
145 | struct inode *h_i; | |
146 | ||
147 | h_i = au_hinode(iinfo, bindex)->hi_inode; | |
148 | if (h_i | |
149 | && !h_i->i_nlink | |
150 | && !(h_i->i_state & I_LINKABLE)) | |
151 | au_set_h_iptr(inode, bindex, NULL, 0); | |
152 | } | |
153 | } | |
154 | ||
155 | iinfo->ii_btop = -1; | |
156 | iinfo->ii_bbot = -1; | |
157 | bbot = au_sbbot(inode->i_sb); | |
158 | for (bindex = 0; bindex <= bbot; bindex++) | |
159 | if (au_hinode(iinfo, bindex)->hi_inode) { | |
160 | iinfo->ii_btop = bindex; | |
161 | break; | |
162 | } | |
163 | if (iinfo->ii_btop >= 0) | |
164 | for (bindex = bbot; bindex >= iinfo->ii_btop; bindex--) | |
165 | if (au_hinode(iinfo, bindex)->hi_inode) { | |
166 | iinfo->ii_bbot = bindex; | |
167 | break; | |
168 | } | |
169 | AuDebugOn(iinfo->ii_btop > iinfo->ii_bbot); | |
170 | } | |
171 | ||
172 | /* ---------------------------------------------------------------------- */ | |
173 | ||
174 | void au_icntnr_init_once(void *_c) | |
175 | { | |
176 | struct au_icntnr *c = _c; | |
177 | struct au_iinfo *iinfo = &c->iinfo; | |
178 | ||
179 | spin_lock_init(&iinfo->ii_generation.ig_spin); | |
180 | au_rw_init(&iinfo->ii_rwsem); | |
181 | inode_init_once(&c->vfs_inode); | |
182 | } | |
183 | ||
184 | void au_hinode_init(struct au_hinode *hinode) | |
185 | { | |
186 | hinode->hi_inode = NULL; | |
187 | hinode->hi_id = -1; | |
188 | au_hn_init(hinode); | |
189 | hinode->hi_whdentry = NULL; | |
190 | } | |
191 | ||
192 | int au_iinfo_init(struct inode *inode) | |
193 | { | |
194 | struct au_iinfo *iinfo; | |
195 | struct super_block *sb; | |
196 | struct au_hinode *hi; | |
197 | int nbr, i; | |
198 | ||
199 | sb = inode->i_sb; | |
200 | iinfo = &(container_of(inode, struct au_icntnr, vfs_inode)->iinfo); | |
201 | nbr = au_sbbot(sb) + 1; | |
202 | if (unlikely(nbr <= 0)) | |
203 | nbr = 1; | |
204 | hi = kmalloc_array(nbr, sizeof(*iinfo->ii_hinode), GFP_NOFS); | |
205 | if (hi) { | |
206 | au_ninodes_inc(sb); | |
207 | ||
208 | iinfo->ii_hinode = hi; | |
209 | for (i = 0; i < nbr; i++, hi++) | |
210 | au_hinode_init(hi); | |
211 | ||
212 | iinfo->ii_generation.ig_generation = au_sigen(sb); | |
213 | iinfo->ii_btop = -1; | |
214 | iinfo->ii_bbot = -1; | |
215 | iinfo->ii_vdir = NULL; | |
216 | return 0; | |
217 | } | |
218 | return -ENOMEM; | |
219 | } | |
220 | ||
221 | int au_hinode_realloc(struct au_iinfo *iinfo, int nbr, int may_shrink) | |
222 | { | |
223 | int err, i; | |
224 | struct au_hinode *hip; | |
225 | ||
226 | AuRwMustWriteLock(&iinfo->ii_rwsem); | |
227 | ||
228 | err = -ENOMEM; | |
229 | hip = au_krealloc(iinfo->ii_hinode, sizeof(*hip) * nbr, GFP_NOFS, | |
230 | may_shrink); | |
231 | if (hip) { | |
232 | iinfo->ii_hinode = hip; | |
233 | i = iinfo->ii_bbot + 1; | |
234 | hip += i; | |
235 | for (; i < nbr; i++, hip++) | |
236 | au_hinode_init(hip); | |
237 | err = 0; | |
238 | } | |
239 | ||
240 | return err; | |
241 | } | |
242 | ||
243 | void au_iinfo_fin(struct inode *inode) | |
244 | { | |
245 | struct au_iinfo *iinfo; | |
246 | struct au_hinode *hi; | |
247 | struct super_block *sb; | |
248 | aufs_bindex_t bindex, bbot; | |
249 | const unsigned char unlinked = !inode->i_nlink; | |
250 | ||
251 | AuDebugOn(au_is_bad_inode(inode)); | |
252 | ||
253 | sb = inode->i_sb; | |
254 | au_ninodes_dec(sb); | |
255 | if (si_pid_test(sb)) | |
256 | au_xino_delete_inode(inode, unlinked); | |
257 | else { | |
258 | /* | |
259 | * it is safe to hide the dependency between sbinfo and | |
260 | * sb->s_umount. | |
261 | */ | |
262 | lockdep_off(); | |
263 | si_noflush_read_lock(sb); | |
264 | au_xino_delete_inode(inode, unlinked); | |
265 | si_read_unlock(sb); | |
266 | lockdep_on(); | |
267 | } | |
268 | ||
269 | iinfo = au_ii(inode); | |
270 | if (iinfo->ii_vdir) | |
271 | au_vdir_free(iinfo->ii_vdir); | |
272 | ||
273 | bindex = iinfo->ii_btop; | |
274 | if (bindex >= 0) { | |
275 | hi = au_hinode(iinfo, bindex); | |
276 | bbot = iinfo->ii_bbot; | |
277 | while (bindex++ <= bbot) { | |
278 | if (hi->hi_inode) | |
279 | au_hiput(hi); | |
280 | hi++; | |
281 | } | |
282 | } | |
283 | kfree(iinfo->ii_hinode); | |
284 | AuRwDestroy(&iinfo->ii_rwsem); | |
285 | } |