Merge branch 'stable-3.2' into pandora-3.2
[pandora-kernel.git] / fs / aufs / dinfo.c
1 /*
2  * Copyright (C) 2005-2013 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, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17  */
18
19 /*
20  * dentry private data
21  */
22
23 #include "aufs.h"
24
25 void au_di_init_once(void *_dinfo)
26 {
27         struct au_dinfo *dinfo = _dinfo;
28         static struct lock_class_key aufs_di;
29
30         au_rw_init(&dinfo->di_rwsem);
31         au_rw_class(&dinfo->di_rwsem, &aufs_di);
32 }
33
34 struct au_dinfo *au_di_alloc(struct super_block *sb, unsigned int lsc)
35 {
36         struct au_dinfo *dinfo;
37         int nbr, i;
38
39         dinfo = au_cache_alloc_dinfo();
40         if (unlikely(!dinfo))
41                 goto out;
42
43         nbr = au_sbend(sb) + 1;
44         if (nbr <= 0)
45                 nbr = 1;
46         dinfo->di_hdentry = kcalloc(nbr, sizeof(*dinfo->di_hdentry), GFP_NOFS);
47         if (dinfo->di_hdentry) {
48                 au_rw_write_lock_nested(&dinfo->di_rwsem, lsc);
49                 dinfo->di_bstart = -1;
50                 dinfo->di_bend = -1;
51                 dinfo->di_bwh = -1;
52                 dinfo->di_bdiropq = -1;
53                 for (i = 0; i < nbr; i++)
54                         dinfo->di_hdentry[i].hd_id = -1;
55                 goto out;
56         }
57
58         au_cache_free_dinfo(dinfo);
59         dinfo = NULL;
60
61 out:
62         return dinfo;
63 }
64
65 void au_di_free(struct au_dinfo *dinfo)
66 {
67         struct au_hdentry *p;
68         aufs_bindex_t bend, bindex;
69
70         /* dentry may not be revalidated */
71         bindex = dinfo->di_bstart;
72         if (bindex >= 0) {
73                 bend = dinfo->di_bend;
74                 p = dinfo->di_hdentry + bindex;
75                 while (bindex++ <= bend)
76                         au_hdput(p++);
77         }
78         kfree(dinfo->di_hdentry);
79         au_cache_free_dinfo(dinfo);
80 }
81
82 void au_di_swap(struct au_dinfo *a, struct au_dinfo *b)
83 {
84         struct au_hdentry *p;
85         aufs_bindex_t bi;
86
87         AuRwMustWriteLock(&a->di_rwsem);
88         AuRwMustWriteLock(&b->di_rwsem);
89
90 #define DiSwap(v, name)                         \
91         do {                                    \
92                 v = a->di_##name;               \
93                 a->di_##name = b->di_##name;    \
94                 b->di_##name = v;               \
95         } while (0)
96
97         DiSwap(p, hdentry);
98         DiSwap(bi, bstart);
99         DiSwap(bi, bend);
100         DiSwap(bi, bwh);
101         DiSwap(bi, bdiropq);
102         /* smp_mb(); */
103
104 #undef DiSwap
105 }
106
107 void au_di_cp(struct au_dinfo *dst, struct au_dinfo *src)
108 {
109         AuRwMustWriteLock(&dst->di_rwsem);
110         AuRwMustWriteLock(&src->di_rwsem);
111
112         dst->di_bstart = src->di_bstart;
113         dst->di_bend = src->di_bend;
114         dst->di_bwh = src->di_bwh;
115         dst->di_bdiropq = src->di_bdiropq;
116         /* smp_mb(); */
117 }
118
119 int au_di_init(struct dentry *dentry)
120 {
121         int err;
122         struct super_block *sb;
123         struct au_dinfo *dinfo;
124
125         err = 0;
126         sb = dentry->d_sb;
127         dinfo = au_di_alloc(sb, AuLsc_DI_CHILD);
128         if (dinfo) {
129                 atomic_set(&dinfo->di_generation, au_sigen(sb));
130                 /* smp_mb(); */ /* atomic_set */
131                 dentry->d_fsdata = dinfo;
132         } else
133                 err = -ENOMEM;
134
135         return err;
136 }
137
138 void au_di_fin(struct dentry *dentry)
139 {
140         struct au_dinfo *dinfo;
141
142         dinfo = au_di(dentry);
143         AuRwDestroy(&dinfo->di_rwsem);
144         au_di_free(dinfo);
145 }
146
147 int au_di_realloc(struct au_dinfo *dinfo, int nbr)
148 {
149         int err, sz;
150         struct au_hdentry *hdp;
151
152         AuRwMustWriteLock(&dinfo->di_rwsem);
153
154         err = -ENOMEM;
155         sz = sizeof(*hdp) * (dinfo->di_bend + 1);
156         if (!sz)
157                 sz = sizeof(*hdp);
158         hdp = au_kzrealloc(dinfo->di_hdentry, sz, sizeof(*hdp) * nbr, GFP_NOFS);
159         if (hdp) {
160                 dinfo->di_hdentry = hdp;
161                 err = 0;
162         }
163
164         return err;
165 }
166
167 /* ---------------------------------------------------------------------- */
168
169 static void do_ii_write_lock(struct inode *inode, unsigned int lsc)
170 {
171         switch (lsc) {
172         case AuLsc_DI_CHILD:
173                 ii_write_lock_child(inode);
174                 break;
175         case AuLsc_DI_CHILD2:
176                 ii_write_lock_child2(inode);
177                 break;
178         case AuLsc_DI_CHILD3:
179                 ii_write_lock_child3(inode);
180                 break;
181         case AuLsc_DI_PARENT:
182                 ii_write_lock_parent(inode);
183                 break;
184         case AuLsc_DI_PARENT2:
185                 ii_write_lock_parent2(inode);
186                 break;
187         case AuLsc_DI_PARENT3:
188                 ii_write_lock_parent3(inode);
189                 break;
190         default:
191                 BUG();
192         }
193 }
194
195 static void do_ii_read_lock(struct inode *inode, unsigned int lsc)
196 {
197         switch (lsc) {
198         case AuLsc_DI_CHILD:
199                 ii_read_lock_child(inode);
200                 break;
201         case AuLsc_DI_CHILD2:
202                 ii_read_lock_child2(inode);
203                 break;
204         case AuLsc_DI_CHILD3:
205                 ii_read_lock_child3(inode);
206                 break;
207         case AuLsc_DI_PARENT:
208                 ii_read_lock_parent(inode);
209                 break;
210         case AuLsc_DI_PARENT2:
211                 ii_read_lock_parent2(inode);
212                 break;
213         case AuLsc_DI_PARENT3:
214                 ii_read_lock_parent3(inode);
215                 break;
216         default:
217                 BUG();
218         }
219 }
220
221 void di_read_lock(struct dentry *d, int flags, unsigned int lsc)
222 {
223         au_rw_read_lock_nested(&au_di(d)->di_rwsem, lsc);
224         if (d->d_inode) {
225                 if (au_ftest_lock(flags, IW))
226                         do_ii_write_lock(d->d_inode, lsc);
227                 else if (au_ftest_lock(flags, IR))
228                         do_ii_read_lock(d->d_inode, lsc);
229         }
230 }
231
232 void di_read_unlock(struct dentry *d, int flags)
233 {
234         if (d->d_inode) {
235                 if (au_ftest_lock(flags, IW)) {
236                         au_dbg_verify_dinode(d);
237                         ii_write_unlock(d->d_inode);
238                 } else if (au_ftest_lock(flags, IR)) {
239                         au_dbg_verify_dinode(d);
240                         ii_read_unlock(d->d_inode);
241                 }
242         }
243         au_rw_read_unlock(&au_di(d)->di_rwsem);
244 }
245
246 void di_downgrade_lock(struct dentry *d, int flags)
247 {
248         if (d->d_inode && au_ftest_lock(flags, IR))
249                 ii_downgrade_lock(d->d_inode);
250         au_rw_dgrade_lock(&au_di(d)->di_rwsem);
251 }
252
253 void di_write_lock(struct dentry *d, unsigned int lsc)
254 {
255         au_rw_write_lock_nested(&au_di(d)->di_rwsem, lsc);
256         if (d->d_inode)
257                 do_ii_write_lock(d->d_inode, lsc);
258 }
259
260 void di_write_unlock(struct dentry *d)
261 {
262         au_dbg_verify_dinode(d);
263         if (d->d_inode)
264                 ii_write_unlock(d->d_inode);
265         au_rw_write_unlock(&au_di(d)->di_rwsem);
266 }
267
268 void di_write_lock2_child(struct dentry *d1, struct dentry *d2, int isdir)
269 {
270         AuDebugOn(d1 == d2
271                   || d1->d_inode == d2->d_inode
272                   || d1->d_sb != d2->d_sb);
273
274         if (isdir && au_test_subdir(d1, d2)) {
275                 di_write_lock_child(d1);
276                 di_write_lock_child2(d2);
277         } else {
278                 /* there should be no races */
279                 di_write_lock_child(d2);
280                 di_write_lock_child2(d1);
281         }
282 }
283
284 void di_write_lock2_parent(struct dentry *d1, struct dentry *d2, int isdir)
285 {
286         AuDebugOn(d1 == d2
287                   || d1->d_inode == d2->d_inode
288                   || d1->d_sb != d2->d_sb);
289
290         if (isdir && au_test_subdir(d1, d2)) {
291                 di_write_lock_parent(d1);
292                 di_write_lock_parent2(d2);
293         } else {
294                 /* there should be no races */
295                 di_write_lock_parent(d2);
296                 di_write_lock_parent2(d1);
297         }
298 }
299
300 void di_write_unlock2(struct dentry *d1, struct dentry *d2)
301 {
302         di_write_unlock(d1);
303         if (d1->d_inode == d2->d_inode)
304                 au_rw_write_unlock(&au_di(d2)->di_rwsem);
305         else
306                 di_write_unlock(d2);
307 }
308
309 /* ---------------------------------------------------------------------- */
310
311 struct dentry *au_h_dptr(struct dentry *dentry, aufs_bindex_t bindex)
312 {
313         struct dentry *d;
314
315         DiMustAnyLock(dentry);
316
317         if (au_dbstart(dentry) < 0 || bindex < au_dbstart(dentry))
318                 return NULL;
319         AuDebugOn(bindex < 0);
320         d = au_di(dentry)->di_hdentry[0 + bindex].hd_dentry;
321         AuDebugOn(d && d->d_count <= 0);
322         return d;
323 }
324
325 /*
326  * extended version of au_h_dptr().
327  * returns a hashed and positive h_dentry in bindex, NULL, or error.
328  */
329 struct dentry *au_h_d_alias(struct dentry *dentry, aufs_bindex_t bindex)
330 {
331         struct dentry *h_dentry;
332         struct inode *inode, *h_inode;
333
334         inode = dentry->d_inode;
335         AuDebugOn(!inode);
336
337         h_dentry = NULL;
338         if (au_dbstart(dentry) <= bindex
339             && bindex <= au_dbend(dentry))
340                 h_dentry = au_h_dptr(dentry, bindex);
341         if (h_dentry && !au_d_hashed_positive(h_dentry)) {
342                 dget(h_dentry);
343                 goto out; /* success */
344         }
345
346         AuDebugOn(bindex < au_ibstart(inode));
347         AuDebugOn(au_ibend(inode) < bindex);
348         h_inode = au_h_iptr(inode, bindex);
349         h_dentry = d_find_alias(h_inode);
350         if (h_dentry) {
351                 if (!IS_ERR(h_dentry)) {
352                         if (!au_d_hashed_positive(h_dentry))
353                                 goto out; /* success */
354                         dput(h_dentry);
355                 } else
356                         goto out;
357         }
358
359         if (au_opt_test(au_mntflags(dentry->d_sb), PLINK)) {
360                 h_dentry = au_plink_lkup(inode, bindex);
361                 AuDebugOn(!h_dentry);
362                 if (!IS_ERR(h_dentry)) {
363                         if (!au_d_hashed_positive(h_dentry))
364                                 goto out; /* success */
365                         dput(h_dentry);
366                         h_dentry = NULL;
367                 }
368         }
369
370 out:
371         AuDbgDentry(h_dentry);
372         return h_dentry;
373 }
374
375 aufs_bindex_t au_dbtail(struct dentry *dentry)
376 {
377         aufs_bindex_t bend, bwh;
378
379         bend = au_dbend(dentry);
380         if (0 <= bend) {
381                 bwh = au_dbwh(dentry);
382                 if (!bwh)
383                         return bwh;
384                 if (0 < bwh && bwh < bend)
385                         return bwh - 1;
386         }
387         return bend;
388 }
389
390 aufs_bindex_t au_dbtaildir(struct dentry *dentry)
391 {
392         aufs_bindex_t bend, bopq;
393
394         bend = au_dbtail(dentry);
395         if (0 <= bend) {
396                 bopq = au_dbdiropq(dentry);
397                 if (0 <= bopq && bopq < bend)
398                         bend = bopq;
399         }
400         return bend;
401 }
402
403 /* ---------------------------------------------------------------------- */
404
405 void au_set_h_dptr(struct dentry *dentry, aufs_bindex_t bindex,
406                    struct dentry *h_dentry)
407 {
408         struct au_hdentry *hd = au_di(dentry)->di_hdentry + bindex;
409         struct au_branch *br;
410
411         DiMustWriteLock(dentry);
412
413         au_hdput(hd);
414         hd->hd_dentry = h_dentry;
415         if (h_dentry) {
416                 br = au_sbr(dentry->d_sb, bindex);
417                 hd->hd_id = br->br_id;
418         }
419 }
420
421 int au_dbrange_test(struct dentry *dentry)
422 {
423         int err;
424         aufs_bindex_t bstart, bend;
425
426         err = 0;
427         bstart = au_dbstart(dentry);
428         bend = au_dbend(dentry);
429         if (bstart >= 0)
430                 AuDebugOn(bend < 0 && bstart > bend);
431         else {
432                 err = -EIO;
433                 AuDebugOn(bend >= 0);
434         }
435
436         return err;
437 }
438
439 int au_digen_test(struct dentry *dentry, unsigned int sigen)
440 {
441         int err;
442
443         err = 0;
444         if (unlikely(au_digen(dentry) != sigen
445                      || au_iigen_test(dentry->d_inode, sigen)))
446                 err = -EIO;
447
448         return err;
449 }
450
451 void au_update_digen(struct dentry *dentry)
452 {
453         atomic_set(&au_di(dentry)->di_generation, au_sigen(dentry->d_sb));
454         /* smp_mb(); */ /* atomic_set */
455 }
456
457 void au_update_dbrange(struct dentry *dentry, int do_put_zero)
458 {
459         struct au_dinfo *dinfo;
460         struct dentry *h_d;
461         struct au_hdentry *hdp;
462
463         DiMustWriteLock(dentry);
464
465         dinfo = au_di(dentry);
466         if (!dinfo || dinfo->di_bstart < 0)
467                 return;
468
469         hdp = dinfo->di_hdentry;
470         if (do_put_zero) {
471                 aufs_bindex_t bindex, bend;
472
473                 bend = dinfo->di_bend;
474                 for (bindex = dinfo->di_bstart; bindex <= bend; bindex++) {
475                         h_d = hdp[0 + bindex].hd_dentry;
476                         if (h_d && !h_d->d_inode)
477                                 au_set_h_dptr(dentry, bindex, NULL);
478                 }
479         }
480
481         dinfo->di_bstart = -1;
482         while (++dinfo->di_bstart <= dinfo->di_bend)
483                 if (hdp[0 + dinfo->di_bstart].hd_dentry)
484                         break;
485         if (dinfo->di_bstart > dinfo->di_bend) {
486                 dinfo->di_bstart = -1;
487                 dinfo->di_bend = -1;
488                 return;
489         }
490
491         dinfo->di_bend++;
492         while (0 <= --dinfo->di_bend)
493                 if (hdp[0 + dinfo->di_bend].hd_dentry)
494                         break;
495         AuDebugOn(dinfo->di_bstart > dinfo->di_bend || dinfo->di_bend < 0);
496 }
497
498 void au_update_dbstart(struct dentry *dentry)
499 {
500         aufs_bindex_t bindex, bend;
501         struct dentry *h_dentry;
502
503         bend = au_dbend(dentry);
504         for (bindex = au_dbstart(dentry); bindex <= bend; bindex++) {
505                 h_dentry = au_h_dptr(dentry, bindex);
506                 if (!h_dentry)
507                         continue;
508                 if (h_dentry->d_inode) {
509                         au_set_dbstart(dentry, bindex);
510                         return;
511                 }
512                 au_set_h_dptr(dentry, bindex, NULL);
513         }
514 }
515
516 void au_update_dbend(struct dentry *dentry)
517 {
518         aufs_bindex_t bindex, bstart;
519         struct dentry *h_dentry;
520
521         bstart = au_dbstart(dentry);
522         for (bindex = au_dbend(dentry); bindex >= bstart; bindex--) {
523                 h_dentry = au_h_dptr(dentry, bindex);
524                 if (!h_dentry)
525                         continue;
526                 if (h_dentry->d_inode) {
527                         au_set_dbend(dentry, bindex);
528                         return;
529                 }
530                 au_set_h_dptr(dentry, bindex, NULL);
531         }
532 }
533
534 int au_find_dbindex(struct dentry *dentry, struct dentry *h_dentry)
535 {
536         aufs_bindex_t bindex, bend;
537
538         bend = au_dbend(dentry);
539         for (bindex = au_dbstart(dentry); bindex <= bend; bindex++)
540                 if (au_h_dptr(dentry, bindex) == h_dentry)
541                         return bindex;
542         return -1;
543 }