2
* Copyright (C) 2005-2011 Junjiro R. Okajima
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.
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.
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
20
* virtual or vertical directory
23
#include <linux/hash.h>
26
static unsigned int calc_size(int nlen)
28
return ALIGN(sizeof(struct au_vdir_de) + nlen, sizeof(ino_t));
31
static int set_deblk_end(union au_vdir_deblk_p *p,
32
union au_vdir_deblk_p *deblk_end)
34
if (calc_size(0) <= deblk_end->deblk - p->deblk) {
35
p->de->de_str.len = 0;
39
return -1; /* error */
42
/* returns true or false */
43
static int is_deblk_end(union au_vdir_deblk_p *p,
44
union au_vdir_deblk_p *deblk_end)
46
if (calc_size(0) <= deblk_end->deblk - p->deblk)
47
return !p->de->de_str.len;
51
static unsigned char *last_deblk(struct au_vdir *vdir)
53
return vdir->vd_deblk[vdir->vd_nblk - 1];
56
/* ---------------------------------------------------------------------- */
58
/* estimate the apropriate size for name hash table */
59
unsigned int au_rdhash_est(loff_t sz)
67
if (sz < AUFS_RDHASH_DEF)
69
/* pr_info("n %u\n", n); */
74
* the allocated memory has to be freed by
75
* au_nhash_wh_free() or au_nhash_de_free().
77
int au_nhash_alloc(struct au_nhash *nhash, unsigned int num_hash, gfp_t gfp)
79
struct hlist_head *head;
82
head = kmalloc(sizeof(*nhash->nh_head) * num_hash, gfp);
84
nhash->nh_num = num_hash;
85
nhash->nh_head = head;
86
for (u = 0; u < num_hash; u++)
87
INIT_HLIST_HEAD(head++);
88
return 0; /* success */
94
static void nhash_count(struct hlist_head *head)
98
struct hlist_node *pos;
101
hlist_for_each(pos, head)
107
static void au_nhash_wh_do_free(struct hlist_head *head)
109
struct au_vdir_wh *tpos;
110
struct hlist_node *pos, *node;
112
hlist_for_each_entry_safe(tpos, pos, node, head, wh_hash) {
113
/* hlist_del(pos); */
118
static void au_nhash_de_do_free(struct hlist_head *head)
120
struct au_vdir_dehstr *tpos;
121
struct hlist_node *pos, *node;
123
hlist_for_each_entry_safe(tpos, pos, node, head, hash) {
124
/* hlist_del(pos); */
125
au_cache_free_vdir_dehstr(tpos);
129
static void au_nhash_do_free(struct au_nhash *nhash,
130
void (*free)(struct hlist_head *head))
133
struct hlist_head *head;
139
head = nhash->nh_head;
144
kfree(nhash->nh_head);
147
void au_nhash_wh_free(struct au_nhash *whlist)
149
au_nhash_do_free(whlist, au_nhash_wh_do_free);
152
static void au_nhash_de_free(struct au_nhash *delist)
154
au_nhash_do_free(delist, au_nhash_de_do_free);
157
/* ---------------------------------------------------------------------- */
159
int au_nhash_test_longer_wh(struct au_nhash *whlist, aufs_bindex_t btgt,
164
struct hlist_head *head;
165
struct au_vdir_wh *tpos;
166
struct hlist_node *pos;
170
head = whlist->nh_head;
171
for (u = 0; u < n; u++, head++)
172
hlist_for_each_entry(tpos, pos, head, wh_hash)
173
if (tpos->wh_bindex == btgt && ++num > limit)
178
static struct hlist_head *au_name_hash(struct au_nhash *nhash,
183
/* const unsigned int magic_bit = 12; */
185
AuDebugOn(!nhash->nh_num || !nhash->nh_head);
190
/* v = hash_long(v, magic_bit); */
192
return nhash->nh_head + v;
195
static int au_nhash_test_name(struct au_vdir_destr *str, const char *name,
198
return str->len == nlen && !memcmp(str->name, name, nlen);
201
/* returns found or not */
202
int au_nhash_test_known_wh(struct au_nhash *whlist, char *name, int nlen)
204
struct hlist_head *head;
205
struct au_vdir_wh *tpos;
206
struct hlist_node *pos;
207
struct au_vdir_destr *str;
209
head = au_name_hash(whlist, name, nlen);
210
hlist_for_each_entry(tpos, pos, head, wh_hash) {
212
AuDbg("%.*s\n", str->len, str->name);
213
if (au_nhash_test_name(str, name, nlen))
219
/* returns found(true) or not */
220
static int test_known(struct au_nhash *delist, char *name, int nlen)
222
struct hlist_head *head;
223
struct au_vdir_dehstr *tpos;
224
struct hlist_node *pos;
225
struct au_vdir_destr *str;
227
head = au_name_hash(delist, name, nlen);
228
hlist_for_each_entry(tpos, pos, head, hash) {
230
AuDbg("%.*s\n", str->len, str->name);
231
if (au_nhash_test_name(str, name, nlen))
237
static void au_shwh_init_wh(struct au_vdir_wh *wh, ino_t ino,
238
unsigned char d_type)
240
#ifdef CONFIG_AUFS_SHWH
242
wh->wh_type = d_type;
246
/* ---------------------------------------------------------------------- */
248
int au_nhash_append_wh(struct au_nhash *whlist, char *name, int nlen, ino_t ino,
249
unsigned int d_type, aufs_bindex_t bindex,
253
struct au_vdir_destr *str;
254
struct au_vdir_wh *wh;
256
AuDbg("%.*s\n", nlen, name);
257
AuDebugOn(!whlist->nh_num || !whlist->nh_head);
260
wh = kmalloc(sizeof(*wh) + nlen, GFP_NOFS);
265
wh->wh_bindex = bindex;
267
au_shwh_init_wh(wh, ino, d_type);
270
memcpy(str->name, name, nlen);
271
hlist_add_head(&wh->wh_hash, au_name_hash(whlist, name, nlen));
278
static int append_deblk(struct au_vdir *vdir)
282
const unsigned int deblk_sz = vdir->vd_deblk_sz;
283
union au_vdir_deblk_p p, deblk_end;
287
o = krealloc(vdir->vd_deblk, sizeof(*o) * (vdir->vd_nblk + 1),
293
p.deblk = kmalloc(deblk_sz, GFP_NOFS);
295
ul = vdir->vd_nblk++;
296
vdir->vd_deblk[ul] = p.deblk;
297
vdir->vd_last.ul = ul;
298
vdir->vd_last.p.deblk = p.deblk;
299
deblk_end.deblk = p.deblk + deblk_sz;
300
err = set_deblk_end(&p, &deblk_end);
307
static int append_de(struct au_vdir *vdir, char *name, int nlen, ino_t ino,
308
unsigned int d_type, struct au_nhash *delist)
312
const unsigned int deblk_sz = vdir->vd_deblk_sz;
313
union au_vdir_deblk_p p, *room, deblk_end;
314
struct au_vdir_dehstr *dehstr;
316
p.deblk = last_deblk(vdir);
317
deblk_end.deblk = p.deblk + deblk_sz;
318
room = &vdir->vd_last.p;
319
AuDebugOn(room->deblk < p.deblk || deblk_end.deblk <= room->deblk
320
|| !is_deblk_end(room, &deblk_end));
322
sz = calc_size(nlen);
323
if (unlikely(sz > deblk_end.deblk - room->deblk)) {
324
err = append_deblk(vdir);
328
p.deblk = last_deblk(vdir);
329
deblk_end.deblk = p.deblk + deblk_sz;
331
AuDebugOn(room->deblk != p.deblk);
335
dehstr = au_cache_alloc_vdir_dehstr();
336
if (unlikely(!dehstr))
339
dehstr->str = &room->de->de_str;
340
hlist_add_head(&dehstr->hash, au_name_hash(delist, name, nlen));
341
room->de->de_ino = ino;
342
room->de->de_type = d_type;
343
room->de->de_str.len = nlen;
344
memcpy(room->de->de_str.name, name, nlen);
348
if (unlikely(set_deblk_end(room, &deblk_end)))
349
err = append_deblk(vdir);
356
/* ---------------------------------------------------------------------- */
358
void au_vdir_free(struct au_vdir *vdir)
360
unsigned char **deblk;
362
deblk = vdir->vd_deblk;
363
while (vdir->vd_nblk--)
365
kfree(vdir->vd_deblk);
366
au_cache_free_vdir(vdir);
369
static struct au_vdir *alloc_vdir(struct file *file)
371
struct au_vdir *vdir;
372
struct super_block *sb;
375
sb = file->f_dentry->d_sb;
379
vdir = au_cache_alloc_vdir();
383
vdir->vd_deblk = kzalloc(sizeof(*vdir->vd_deblk), GFP_NOFS);
384
if (unlikely(!vdir->vd_deblk))
387
vdir->vd_deblk_sz = au_sbi(sb)->si_rdblk;
388
if (!vdir->vd_deblk_sz) {
389
/* estimate the apropriate size for deblk */
390
vdir->vd_deblk_sz = au_dir_size(file, /*dentry*/NULL);
391
/* pr_info("vd_deblk_sz %u\n", vdir->vd_deblk_sz); */
394
vdir->vd_version = 0;
396
err = append_deblk(vdir);
398
return vdir; /* success */
400
kfree(vdir->vd_deblk);
403
au_cache_free_vdir(vdir);
409
static int reinit_vdir(struct au_vdir *vdir)
412
union au_vdir_deblk_p p, deblk_end;
414
while (vdir->vd_nblk > 1) {
415
kfree(vdir->vd_deblk[vdir->vd_nblk - 1]);
416
/* vdir->vd_deblk[vdir->vd_nblk - 1] = NULL; */
419
p.deblk = vdir->vd_deblk[0];
420
deblk_end.deblk = p.deblk + vdir->vd_deblk_sz;
421
err = set_deblk_end(&p, &deblk_end);
422
/* keep vd_dblk_sz */
423
vdir->vd_last.ul = 0;
424
vdir->vd_last.p.deblk = vdir->vd_deblk[0];
425
vdir->vd_version = 0;
431
/* ---------------------------------------------------------------------- */
433
#define AuFillVdir_CALLED 1
434
#define AuFillVdir_WHABLE (1 << 1)
435
#define AuFillVdir_SHWH (1 << 2)
436
#define au_ftest_fillvdir(flags, name) ((flags) & AuFillVdir_##name)
437
#define au_fset_fillvdir(flags, name) \
438
do { (flags) |= AuFillVdir_##name; } while (0)
439
#define au_fclr_fillvdir(flags, name) \
440
do { (flags) &= ~AuFillVdir_##name; } while (0)
442
#ifndef CONFIG_AUFS_SHWH
443
#undef AuFillVdir_SHWH
444
#define AuFillVdir_SHWH 0
447
struct fillvdir_arg {
449
struct au_vdir *vdir;
450
struct au_nhash delist;
451
struct au_nhash whlist;
452
aufs_bindex_t bindex;
457
static int fillvdir(void *__arg, const char *__name, int nlen,
458
loff_t offset __maybe_unused, u64 h_ino,
461
struct fillvdir_arg *arg = __arg;
462
char *name = (void *)__name;
463
struct super_block *sb;
465
const unsigned char shwh = !!au_ftest_fillvdir(arg->flags, SHWH);
468
sb = arg->file->f_dentry->d_sb;
469
au_fset_fillvdir(arg->flags, CALLED);
471
if (nlen <= AUFS_WH_PFX_LEN
472
|| memcmp(name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) {
473
if (test_known(&arg->delist, name, nlen)
474
|| au_nhash_test_known_wh(&arg->whlist, name, nlen))
475
goto out; /* already exists or whiteouted */
477
sb = arg->file->f_dentry->d_sb;
478
arg->err = au_ino(sb, arg->bindex, h_ino, d_type, &ino);
480
if (unlikely(nlen > AUFS_MAX_NAMELEN))
482
arg->err = append_de(arg->vdir, name, nlen, ino,
483
d_type, &arg->delist);
485
} else if (au_ftest_fillvdir(arg->flags, WHABLE)) {
486
name += AUFS_WH_PFX_LEN;
487
nlen -= AUFS_WH_PFX_LEN;
488
if (au_nhash_test_known_wh(&arg->whlist, name, nlen))
489
goto out; /* already whiteouted */
492
arg->err = au_wh_ino(sb, arg->bindex, h_ino, d_type,
495
if (nlen <= AUFS_MAX_NAMELEN + AUFS_WH_PFX_LEN)
497
arg->err = au_nhash_append_wh
498
(&arg->whlist, name, nlen, ino, d_type,
505
arg->vdir->vd_jiffy = jiffies;
507
AuTraceErr(arg->err);
511
static int au_handle_shwh(struct super_block *sb, struct au_vdir *vdir,
512
struct au_nhash *whlist, struct au_nhash *delist)
514
#ifdef CONFIG_AUFS_SHWH
517
struct hlist_head *head;
518
struct au_vdir_wh *tpos;
519
struct hlist_node *pos, *n;
521
struct au_vdir_destr *destr;
523
AuDebugOn(!au_opt_test(au_mntflags(sb), SHWH));
526
o = p = __getname_gfp(GFP_NOFS);
532
memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
533
p += AUFS_WH_PFX_LEN;
534
for (u = 0; u < nh; u++) {
535
head = whlist->nh_head + u;
536
hlist_for_each_entry_safe(tpos, pos, n, head, wh_hash) {
537
destr = &tpos->wh_str;
538
memcpy(p, destr->name, destr->len);
539
err = append_de(vdir, o, destr->len + AUFS_WH_PFX_LEN,
540
tpos->wh_ino, tpos->wh_type, delist);
556
static int au_do_read_vdir(struct fillvdir_arg *arg)
561
aufs_bindex_t bend, bindex, bstart;
563
struct file *hf, *file;
564
struct super_block *sb;
567
sb = file->f_dentry->d_sb;
570
rdhash = au_sbi(sb)->si_rdhash;
572
rdhash = au_rdhash_est(au_dir_size(file, /*dentry*/NULL));
573
err = au_nhash_alloc(&arg->delist, rdhash, GFP_NOFS);
576
err = au_nhash_alloc(&arg->whlist, rdhash, GFP_NOFS);
583
if (au_opt_test(au_mntflags(sb), SHWH)) {
585
au_fset_fillvdir(arg->flags, SHWH);
587
bstart = au_fbstart(file);
588
bend = au_fbend_dir(file);
589
for (bindex = bstart; !err && bindex <= bend; bindex++) {
590
hf = au_hf_dir(file, bindex);
594
offset = vfsub_llseek(hf, 0, SEEK_SET);
596
if (unlikely(offset))
599
arg->bindex = bindex;
600
au_fclr_fillvdir(arg->flags, WHABLE);
603
&& au_br_whable(au_sbr_perm(sb, bindex))))
604
au_fset_fillvdir(arg->flags, WHABLE);
607
au_fclr_fillvdir(arg->flags, CALLED);
609
err = vfsub_readdir(hf, fillvdir, arg);
612
} while (!err && au_ftest_fillvdir(arg->flags, CALLED));
616
err = au_handle_shwh(sb, arg->vdir, &arg->whlist, &arg->delist);
618
au_nhash_wh_free(&arg->whlist);
621
au_nhash_de_free(&arg->delist);
626
static int read_vdir(struct file *file, int may_read)
629
unsigned long expire;
630
unsigned char do_read;
631
struct fillvdir_arg arg;
633
struct au_vdir *vdir, *allocated;
636
inode = file->f_dentry->d_inode;
638
SiMustAnyLock(inode->i_sb);
642
expire = au_sbi(inode->i_sb)->si_rdcache;
643
vdir = au_ivdir(inode);
646
vdir = alloc_vdir(file);
653
&& (inode->i_version != vdir->vd_version
654
|| time_after(jiffies, vdir->vd_jiffy + expire))) {
656
err = reinit_vdir(vdir);
662
return 0; /* success */
666
err = au_do_read_vdir(&arg);
668
/* file->f_pos = 0; */
669
vdir->vd_version = inode->i_version;
670
vdir->vd_last.ul = 0;
671
vdir->vd_last.p.deblk = vdir->vd_deblk[0];
673
au_set_ivdir(inode, allocated);
674
} else if (allocated)
675
au_vdir_free(allocated);
681
static int copy_vdir(struct au_vdir *tgt, struct au_vdir *src)
685
const unsigned int deblk_sz = src->vd_deblk_sz;
687
AuDebugOn(tgt->vd_nblk != 1);
690
if (tgt->vd_nblk < src->vd_nblk) {
693
p = krealloc(tgt->vd_deblk, sizeof(*p) * src->vd_nblk,
700
if (tgt->vd_deblk_sz != deblk_sz) {
703
tgt->vd_deblk_sz = deblk_sz;
704
p = krealloc(tgt->vd_deblk[0], deblk_sz, GFP_NOFS);
707
tgt->vd_deblk[0] = p;
709
memcpy(tgt->vd_deblk[0], src->vd_deblk[0], deblk_sz);
710
tgt->vd_version = src->vd_version;
711
tgt->vd_jiffy = src->vd_jiffy;
714
for (ul = 1; ul < n; ul++) {
715
tgt->vd_deblk[ul] = kmemdup(src->vd_deblk[ul], deblk_sz,
717
if (unlikely(!tgt->vd_deblk[ul]))
722
tgt->vd_last.ul = tgt->vd_last.ul;
723
tgt->vd_last.p.deblk = tgt->vd_deblk[tgt->vd_last.ul];
724
tgt->vd_last.p.deblk += src->vd_last.p.deblk
725
- src->vd_deblk[src->vd_last.ul];
727
return 0; /* success */
730
rerr = reinit_vdir(tgt);
735
int au_vdir_init(struct file *file)
739
struct au_vdir *vdir_cache, *allocated;
741
err = read_vdir(file, !file->f_pos);
746
vdir_cache = au_fvdir_cache(file);
748
vdir_cache = alloc_vdir(file);
749
err = PTR_ERR(vdir_cache);
750
if (IS_ERR(vdir_cache))
752
allocated = vdir_cache;
753
} else if (!file->f_pos && vdir_cache->vd_version != file->f_version) {
754
err = reinit_vdir(vdir_cache);
758
return 0; /* success */
760
inode = file->f_dentry->d_inode;
761
err = copy_vdir(vdir_cache, au_ivdir(inode));
763
file->f_version = inode->i_version;
765
au_set_fvdir_cache(file, allocated);
766
} else if (allocated)
767
au_vdir_free(allocated);
773
static loff_t calc_offset(struct au_vdir *vdir)
776
union au_vdir_deblk_p p;
778
p.deblk = vdir->vd_deblk[vdir->vd_last.ul];
779
offset = vdir->vd_last.p.deblk - p.deblk;
780
offset += vdir->vd_deblk_sz * vdir->vd_last.ul;
784
/* returns true or false */
785
static int seek_vdir(struct file *file)
788
unsigned int deblk_sz;
791
union au_vdir_deblk_p p, deblk_end;
792
struct au_vdir *vdir_cache;
795
vdir_cache = au_fvdir_cache(file);
796
offset = calc_offset(vdir_cache);
797
AuDbg("offset %lld\n", offset);
798
if (file->f_pos == offset)
801
vdir_cache->vd_last.ul = 0;
802
vdir_cache->vd_last.p.deblk = vdir_cache->vd_deblk[0];
807
deblk_sz = vdir_cache->vd_deblk_sz;
808
ul = div64_u64(file->f_pos, deblk_sz);
809
AuDbg("ul %lu\n", ul);
810
if (ul >= vdir_cache->vd_nblk)
813
n = vdir_cache->vd_nblk;
814
for (; ul < n; ul++) {
815
p.deblk = vdir_cache->vd_deblk[ul];
816
deblk_end.deblk = p.deblk + deblk_sz;
819
while (!is_deblk_end(&p, &deblk_end) && offset < file->f_pos) {
822
l = calc_size(p.de->de_str.len);
826
if (!is_deblk_end(&p, &deblk_end)) {
828
vdir_cache->vd_last.ul = ul;
829
vdir_cache->vd_last.p = p;
840
int au_vdir_fill_de(struct file *file, void *dirent, filldir_t filldir)
843
unsigned int l, deblk_sz;
844
union au_vdir_deblk_p deblk_end;
845
struct au_vdir *vdir_cache;
846
struct au_vdir_de *de;
848
vdir_cache = au_fvdir_cache(file);
849
if (!seek_vdir(file))
852
deblk_sz = vdir_cache->vd_deblk_sz;
854
deblk_end.deblk = vdir_cache->vd_deblk[vdir_cache->vd_last.ul];
855
deblk_end.deblk += deblk_sz;
856
while (!is_deblk_end(&vdir_cache->vd_last.p, &deblk_end)) {
857
de = vdir_cache->vd_last.p.de;
858
AuDbg("%.*s, off%lld, i%lu, dt%d\n",
859
de->de_str.len, de->de_str.name, file->f_pos,
860
(unsigned long)de->de_ino, de->de_type);
861
err = filldir(dirent, de->de_str.name, de->de_str.len,
862
file->f_pos, de->de_ino, de->de_type);
865
/* todo: ignore the error caused by udba? */
870
l = calc_size(de->de_str.len);
871
vdir_cache->vd_last.p.deblk += l;
874
if (vdir_cache->vd_last.ul < vdir_cache->vd_nblk - 1) {
875
vdir_cache->vd_last.ul++;
876
vdir_cache->vd_last.p.deblk
877
= vdir_cache->vd_deblk[vdir_cache->vd_last.ul];
878
file->f_pos = deblk_sz * vdir_cache->vd_last.ul;