16
16
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19
/* $Id: whout.c,v 1.13 2007/05/07 03:46:08 sfjro Exp $ */
19
/* $Id: whout.c,v 1.17 2007/06/04 02:17:35 sfjro Exp $ */
21
21
#include <linux/fs.h>
22
22
#include <linux/namei.h>
49
DEBUG_ON(!name || !len || !wh);
49
AuDebugOn(!name || !len || !wh);
51
if (unlikely(len > PATH_MAX - AUFS_WH_LEN))
51
if (unlikely(len > PATH_MAX - AUFS_WH_PFX_LEN))
52
52
return -ENAMETOOLONG;
54
wh->len = len + AUFS_WH_LEN;
54
wh->len = len + AUFS_WH_PFX_LEN;
55
55
wh->name = p = kmalloc(wh->len, GFP_KERNEL);
56
56
//if (LktrCond) {kfree(p); wh->name = p = NULL;}
58
memcpy(p, AUFS_WH_PFX, AUFS_WH_LEN);
59
memcpy(p + AUFS_WH_LEN, name, len);
58
memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
59
memcpy(p + AUFS_WH_PFX_LEN, name, len);
88
88
LKTRTrace("%.*s/%.*s, lkup{%p, %d}\n", DLNPair(hidden_parent),
89
89
wh_name->len, wh_name->name, lkup->nfsmnt, lkup->dlgt);
90
90
hidden_dir = hidden_parent->d_inode;
91
DEBUG_ON(!S_ISDIR(hidden_dir->i_mode));
91
AuDebugOn(!S_ISDIR(hidden_dir->i_mode));
92
92
IMustLock(hidden_dir);
132
132
LKTRTrace("dentry %.*s\n", DLNPair(hidden_dentry));
133
133
hidden_dir = hidden_dentry->d_inode;
134
DEBUG_ON(!S_ISDIR(hidden_dir->i_mode));
134
AuDebugOn(!S_ISDIR(hidden_dir->i_mode));
135
135
IMustLock(hidden_dir);
137
137
err = is_wh(hidden_dentry, &diropq_name, /*try_sio*/1, lkup);
148
148
#define HEX_LEN 4
149
149
struct dentry *dentry;
151
char defname[AUFS_WH_LEN * 2 + DNAME_INLINE_LEN_MIN + 1 + HEX_LEN + 1],
151
char defname[AUFS_WH_PFX_LEN * 2 + DNAME_INLINE_LEN_MIN + 1
152
+ HEX_LEN + 1], *name, *p;
153
153
static unsigned char cnt;
155
155
LKTRTrace("hp %.*s, prefix %.*s\n",
156
156
DLNPair(hidden_parent), prefix->len, prefix->name);
157
DEBUG_ON(!hidden_parent->d_inode);
157
AuDebugOn(!hidden_parent->d_inode);
158
158
IMustLock(hidden_parent->d_inode);
173
173
// doubly whiteout-ed
174
memcpy(name, AUFS_WH_PFX AUFS_WH_PFX, AUFS_WH_LEN * 2);
175
p = name + AUFS_WH_LEN * 2;
174
memcpy(name, AUFS_WH_PFX AUFS_WH_PFX, AUFS_WH_PFX_LEN * 2);
175
p = name + AUFS_WH_PFX_LEN * 2;
176
176
memcpy(p, prefix->name, prefix->len);
177
177
p += prefix->len;
179
DEBUG_ON(name + len + 1 - p <= HEX_LEN);
179
AuDebugOn(name + len + 1 - p <= HEX_LEN);
181
181
for (i = 0; i < 3; i++) {
182
182
sprintf(p, "%.*d", HEX_LEN, cnt++);
214
214
LKTRTrace("%.*s, b%d\n", DLNPair(dentry), bindex);
215
215
hidden_dentry = au_h_dptr_i(dentry, bindex);
216
DEBUG_ON(!hidden_dentry || !hidden_dentry->d_inode);
217
hidden_parent = hidden_dentry->d_parent;
216
AuDebugOn(!hidden_dentry || !hidden_dentry->d_inode);
217
hidden_parent = dget_parent(hidden_dentry);
218
218
hidden_dir = hidden_parent->d_inode;
219
219
IMustLock(hidden_dir);
247
248
LKTRTrace("hi%lu, wh %.*s, d %p\n", hidden_dir->i_ino,
248
249
DLNPair(wh_dentry), dentry);
249
DEBUG_ON((dentry && dbwh(dentry) == -1)
250
|| !wh_dentry->d_inode
251
|| !S_ISREG(wh_dentry->d_inode->i_mode));
250
AuDebugOn((dentry && dbwh(dentry) == -1)
251
|| !wh_dentry->d_inode
252
|| !S_ISREG(wh_dentry->d_inode->i_mode));
252
253
IMustLock(hidden_dir);
254
255
err = vfsub_unlink(hidden_dir, wh_dentry, dlgt);
367
368
err = PTR_ERR(wh);
370
DEBUG_ON(br->br_wh && br->br_wh != wh);
371
AuDebugOn(br->br_wh && br->br_wh != wh);
372
373
plink = lkup_wh(h_root, base_name + 1, &lkup);
373
374
err = PTR_ERR(plink);
374
375
if (IS_ERR(plink))
375
376
goto out_dput_wh;
376
DEBUG_ON(br->br_plink && br->br_plink != plink);
377
AuDebugOn(br->br_plink && br->br_plink != plink);
379
380
dput(br->br_plink);
486
487
dir = a->sb->s_root->d_inode;
487
hidden_root = a->br->br_wh->d_parent;
488
hidden_root = dget_parent(a->br->br_wh);
488
489
hidden_dir = hidden_root->d_inode;
489
DEBUG_ON(!hidden_dir->i_op || !hidden_dir->i_op->link);
490
AuDebugOn(!hidden_dir->i_op || !hidden_dir->i_op->link);
490
491
hdir_lock(hidden_dir, dir, bindex);
491
492
br_wh_write_lock(a->br);
492
493
err = vfsub_unlink(hidden_dir, a->br->br_wh, /*dlgt*/0);
527
au_wkq_nowait(reinit_br_wh, arg, /*dlgt*/0);
529
wkq_err = au_wkq_nowait(reinit_br_wh, arg, sb, /*dlgt*/0);
530
if (unlikely(wkq_err)) {
531
atomic_dec(&br->br_wh_running);
547
554
LKTRTrace("%.*s\n", DLNPair(wh));
548
555
SiMustReadLock(sb);
549
hidden_parent = wh->d_parent;
556
hidden_parent = dget_parent(wh);
550
557
hidden_dir = hidden_parent->d_inode;
551
558
IMustLock(hidden_dir);
588
596
LKTRTrace("%.*s, bindex %d, do_create %d\n", DLNPair(dentry),
589
597
bindex, do_create);
590
598
hidden_dentry = au_h_dptr_i(dentry, bindex);
591
DEBUG_ON(!hidden_dentry);
599
AuDebugOn(!hidden_dentry);
592
600
hidden_dir = hidden_dentry->d_inode;
593
DEBUG_ON(!hidden_dir || !S_ISDIR(hidden_dir->i_mode));
601
AuDebugOn(!hidden_dir || !S_ISDIR(hidden_dir->i_mode));
594
602
IMustLock(hidden_dir);
596
604
// already checked by au_test_perm().
607
DEBUG_ON(opq_dentry->d_inode);
615
AuDebugOn(opq_dentry->d_inode);
608
616
err = link_or_create_wh(opq_dentry, sb, bindex);
609
617
//if (LktrCond) {vfs_unlink(hidden_dir, opq_dentry); err = -1;}
612
620
goto out; /* success */
615
DEBUG_ON(/* !S_ISDIR(dentry->d_inode->i_mode)
616
* || */!opq_dentry->d_inode);
623
AuDebugOn(/* !S_ISDIR(dentry->d_inode->i_mode)
624
* || */!opq_dentry->d_inode);
617
625
err = vfsub_unlink(hidden_dir, opq_dentry, lkup.dlgt);
618
626
//if (LktrCond) err = -1;
652
660
if (!au_test_perm(hidden_dentry->d_inode, MAY_EXEC | MAY_WRITE, dlgt))
653
661
diropq = do_diropq(dentry, bindex, do_create, dlgt);
655
664
struct do_diropq_args args = {
657
666
.dentry = dentry,
659
668
.do_create = do_create,
662
au_wkq_wait(call_do_diropq, &args, /*dlgt*/0);
671
wkq_err = au_wkq_wait(call_do_diropq, &args, /*dlgt*/0);
672
if (unlikely(wkq_err))
673
diropq = ERR_PTR(wkq_err);
665
676
TraceErrPtr(diropq);
749
760
LKTRTrace("%.*s\n", DLNPair(hidden_parent));
750
761
hidden_dir = hidden_parent->d_inode;
751
762
IMustLock(hidden_dir);
752
DEBUG_ON(IS_RDONLY(hidden_dir));
763
AuDebugOn(IS_RDONLY(hidden_dir));
753
764
//SiMustReadLock(??);
757
768
//if (LktrCond) {__putname(p); wh_name.name = p = NULL;}
758
769
if (unlikely(!wh_name.name))
760
memcpy(p, AUFS_WH_PFX, AUFS_WH_LEN);
771
memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
772
p += AUFS_WH_PFX_LEN;
763
774
// already checked by au_test_perm().
768
779
if (tpos->wh_bindex != bindex)
770
781
str = &tpos->wh_str;
771
if (str->len + AUFS_WH_LEN <= PATH_MAX) {
782
if (str->len + AUFS_WH_PFX_LEN <= PATH_MAX) {
772
783
memcpy(p, str->name, str->len);
773
wh_name.len = AUFS_WH_LEN + str->len;
784
wh_name.len = AUFS_WH_PFX_LEN + str->len;
774
785
err = unlink_wh_name(hidden_parent, &wh_name,
776
787
//if (LktrCond) err = -1;
824
836
DLNPair(hidden_dentry), bindex, dir->i_ino);
826
838
IiMustAnyLock(dir);
827
hidden_dir = hidden_dentry->d_parent->d_inode;
839
h_parent = dget_parent(hidden_dentry);
840
hidden_dir = h_parent->d_inode;
828
841
IMustLock(hidden_dir);
830
843
sb = inode->i_sb;
831
844
lkup.nfsmnt = au_nfsmnt(sb, bindex);
832
845
lkup.dlgt = need_dlgt(sb);
833
846
hidden_inode = hidden_dentry->d_inode;
834
DEBUG_ON(hidden_inode != au_h_iptr_i(inode, bindex));
847
AuDebugOn(hidden_inode != au_h_iptr_i(inode, bindex));
835
848
hdir2_lock(hidden_inode, inode, bindex);
836
849
if (!au_test_perm(hidden_inode, MAY_EXEC | MAY_WRITE, lkup.dlgt))
837
850
err = del_wh_children(whlist, hidden_dentry, bindex, &lkup);
840
854
int dlgt = lkup.dlgt;
841
855
struct del_wh_children_args args = {
850
au_wkq_wait(call_del_wh_children, &args, /*dlgt*/0);
864
wkq_err = au_wkq_wait(call_del_wh_children, &args, /*dlgt*/0);
865
if (unlikely(wkq_err))
851
867
lkup.dlgt = dlgt;
853
869
hdir_unlock(hidden_inode, inode, bindex);
875
static void do_rmdir_whtmp(void *arg)
892
static void rmdir_whtmp_free_args(struct rmdir_whtmp_args *args)
894
dput(args->h_dentry);
895
nhash_fin(&args->whlist);
902
static void do_rmdir_whtmp(void *args)
878
struct rmdir_whtmp_arg *a = arg;
905
struct rmdir_whtmp_args *a = args;
879
906
struct super_block *sb;
881
908
LKTRTrace("%.*s, b%d, dir i%lu\n",
885
912
sb = a->dir->i_sb;
886
914
si_read_lock(sb);
887
915
err = test_ro(sb, a->bindex, NULL);
889
struct inode *hidden_dir = a->h_dentry->d_parent->d_inode;
917
struct dentry *h_parent = dget_parent(a->h_dentry);
918
struct inode *hidden_dir = h_parent->d_inode;
891
920
ii_write_lock_child(a->inode);
892
921
ii_write_lock_parent(a->dir);
896
925
hdir_unlock(hidden_dir, a->dir, a->bindex);
897
926
ii_write_unlock(a->dir);
898
927
ii_write_unlock(a->inode);
901
nhash_fin(&a->whlist);
903
930
si_read_unlock(sb);
931
rmdir_whtmp_free_args(a);
907
932
if (unlikely(err))
908
933
IOErr("err %d\n", err);
911
void kick_rmdir_whtmp(struct dentry *hidden_dentry, struct aufs_nhash *whlist,
936
void kick_rmdir_whtmp(struct dentry *h_dentry, struct aufs_nhash *whlist,
912
937
aufs_bindex_t bindex, struct inode *dir,
913
struct inode *inode, struct rmdir_whtmp_arg *arg)
938
struct inode *inode, struct rmdir_whtmp_args *args)
915
LKTRTrace("%.*s\n", DLNPair(hidden_dentry));
942
LKTRTrace("%.*s\n", DLNPair(h_dentry));
918
945
// all post-process will be done in do_rmdir_whtmp().
919
arg->h_dentry = dget(hidden_dentry);
920
nhash_init(&arg->whlist);
921
nhash_move(&arg->whlist, whlist);
922
arg->bindex = bindex;
923
arg->dir = igrab(dir);
924
arg->inode = igrab(inode);
926
au_wkq_nowait(do_rmdir_whtmp, arg, /*dlgt*/0);
946
args->h_dentry = dget(h_dentry);
947
nhash_init(&args->whlist);
948
nhash_move(&args->whlist, whlist);
949
args->bindex = bindex;
950
args->dir = igrab(dir);
951
args->inode = igrab(inode);
952
wkq_err = au_wkq_nowait(do_rmdir_whtmp, args, dir->i_sb, /*dlgt*/0);
953
if (unlikely(wkq_err)) {
954
Warn("rmdir error %.*s (%d), ignored\n",
955
DLNPair(h_dentry), wkq_err);
956
rmdir_whtmp_free_args(args);