]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blob - fs/aufs/iinfo.c
UBUNTU: SAUCE: Import aufs driver
[mirror_ubuntu-zesty-kernel.git] / fs / aufs / iinfo.c
1 /*
2 * Copyright (C) 2005-2016 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, /*atonce*/0);
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 au_delayed_kfree(iinfo->ii_hinode);
284 AuRwDestroy(&iinfo->ii_rwsem);
285 }