fix shared node reference issue
License: MIT Signed-off-by: Jeromy <jeromyj@gmail.com>
Jeromy committed
Jan 2, 2016 at 13:26 UTC
9aea2c78959e2c01f56e1b7413b8bfb21419dbb7
5 files changed
+97
-13
mfs/dir.go
+3
-3
@@ -258,9 +258,9 @@ func (d *Directory) Mkdir(name string) (*Directory, error) {
258
d.lock.Lock()
259
defer d.lock.Unlock()
260
261
- _, err := d.childDir(name)
261
+ child, err := d.childDir(name)
262
if err == nil {
263
- return nil, os.ErrExist
263
+ return child, os.ErrExist
264
}
265
_, err = d.childFile(name)
266
if err == nil {
@@ -395,7 +395,7 @@ func (d *Directory) GetNode() (*dag.Node, error) {
395
return nil, err
396
}
397
398
- return d.node, nil
398
+ return d.node.Copy(), nil
399
}
400
401
func (d *Directory) Lock() {
mfs/file.go
+6
-3
@@ -65,6 +65,7 @@ func (fi *File) Close() error {
65
if fi.hasChanges {
66
err := fi.mod.Sync()
67
if err != nil {
68
+ fi.Unlock()
69
return err
70
}
71
@@ -74,6 +75,7 @@ func (fi *File) Close() error {
75
// it will manage the lock for us
76
return fi.flushUp()
77
}
78
+ fi.Unlock()
79
80
return nil
81
}
@@ -93,12 +95,13 @@ func (fi *File) flushUp() error {
95
return err
96
}
97
96
- name := fi.name
97
- parent := fi.parent
98
+ //name := fi.name
99
+ //parent := fi.parent
100
101
// explicit unlock *only* before closeChild call
102
fi.Unlock()
101
- return parent.closeChild(name, nd)
103
+ return nil
104
+ //return parent.closeChild(name, nd)
105
}
106
107
// Sync flushes the changes in the file to disk
mfs/mfs_test.go
+58
-2
@@ -576,10 +576,56 @@ func actorRemoveFile(d *Directory) error {
576
return d.Unlink(re.Name)
577
}
578
579
+func actorReadFile(d *Directory) error {
580
+ d, err := randomWalk(d, rand.Intn(6))
581
+ if err != nil {
582
+ return err
583
+ }
584
+
585
+ ents, err := d.List()
586
+ if err != nil {
587
+ return err
588
+ }
589
+
590
+ var files []string
591
+ for _, e := range ents {
592
+ if e.Type == int(TFile) {
593
+ files = append(files, e.Name)
594
+ }
595
+ }
596
+
597
+ if len(files) == 0 {
598
+ return nil
599
+ }
600
+
601
+ fname := files[rand.Intn(len(files))]
602
+ fsn, err := d.Child(fname)
603
+ if err != nil {
604
+ return err
605
+ }
606
+
607
+ fi, ok := fsn.(*File)
608
+ if !ok {
609
+ return errors.New("file wasnt a file, race?")
610
+ }
611
+
612
+ _, err = fi.Size()
613
+ if err != nil {
614
+ return err
615
+ }
616
+
617
+ _, err = ioutil.ReadAll(fi)
618
+ if err != nil {
619
+ return err
620
+ }
621
+
622
+ return fi.Close()
623
+}
624
+
625
func testActor(rt *Root, iterations int, errs chan error) {
626
d := rt.GetValue().(*Directory)
627
for i := 0; i < iterations; i++ {
582
- switch rand.Intn(4) {
628
+ switch rand.Intn(5) {
629
case 0:
630
if err := actorMkdir(d); err != nil {
631
errs <- err
@@ -591,10 +637,20 @@ func testActor(rt *Root, iterations int, errs chan error) {
637
return
638
}
639
case 3:
640
+ continue
641
+ // randomly deleting things
642
+ // doesnt really give us any sort of useful test results.
643
+ // you will never have this in a real environment where
644
+ // you expect anything productive to happen...
645
if err := actorRemoveFile(d); err != nil {
646
errs <- err
647
return
648
}
649
+ case 4:
650
+ if err := actorReadFile(d); err != nil {
651
+ errs <- err
652
+ return
653
+ }
654
}
655
}
656
errs <- nil
@@ -605,7 +661,7 @@ func TestMfsStress(t *testing.T) {
661
defer cancel()
662
_, rt := setupRoot(ctx, t)
663
608
- numroutines := 2
664
+ numroutines := 10
665
666
errs := make(chan error)
667
for i := 0; i < numroutines; i++ {
mfs/ops.go
+5
-5
@@ -99,8 +99,8 @@ func PutNode(r *Root, path string, nd *dag.Node) error {
99
}
100
101
// Mkdir creates a directory at 'path' under the directory 'd', creating
102
-// intermediary directories as needed if 'parents' is set to true
103
-func Mkdir(r *Root, pth string, parents bool, flush bool) error {
102
+// intermediary directories as needed if 'mkparents' is set to true
103
+func Mkdir(r *Root, pth string, mkparents bool, flush bool) error {
104
if pth == "" {
105
return nil
106
}
@@ -116,7 +116,7 @@ func Mkdir(r *Root, pth string, parents bool, flush bool) error {
116
117
if len(parts) == 0 {
118
// this will only happen on 'mkdir /'
119
- if parents {
119
+ if mkparents {
120
return nil
121
}
122
return fmt.Errorf("cannot create directory '/': Already exists")
@@ -125,7 +125,7 @@ func Mkdir(r *Root, pth string, parents bool, flush bool) error {
125
cur := r.GetValue().(*Directory)
126
for i, d := range parts[:len(parts)-1] {
127
fsn, err := cur.Child(d)
128
- if err == os.ErrNotExist && parents {
128
+ if err == os.ErrNotExist && mkparents {
129
mkd, err := cur.Mkdir(d)
130
if err != nil {
131
return err
@@ -144,7 +144,7 @@ func Mkdir(r *Root, pth string, parents bool, flush bool) error {
144
145
final, err := cur.Mkdir(parts[len(parts)-1])
146
if err != nil {
147
- if !parents || err != os.ErrExist {
147
+ if !mkparents || err != os.ErrExist || final == nil {
148
return err
149
}
150
}
test/sharness/t0250-files-api.sh
+25
@@ -352,6 +352,31 @@ test_files_api() {
352
test_expect_success "cleanup looks good" '
353
verify_dir_contents /
354
'
355
+
356
+ # test flush flags
357
+ test_expect_success "mkdir --flush works" '
358
+ ipfs files mkdir --flush --parents /flushed/deep
359
+ '
360
+
361
+ test_expect_success "mkdir --flush works a second time" '
362
+ ipfs files mkdir --flush --parents /flushed/deep
363
+ '
364
+
365
+ test_expect_success "dir looks right" '
366
+ verify_dir_contents / flushed
367
+ '
368
+
369
+ test_expect_success "child dir looks right" '
370
+ verify_dir_contents /flushed deep
371
+ '
372
+
373
+ test_expect_success "cleanup" '
374
+ ipfs files rm -r /flushed
375
+ '
376
+
377
+ test_expect_success "child dir looks right" '
378
+ verify_dir_contents /
379
+ '
380
}
381
382
# test offline and online