@cryptotaxi247 / kubo / commits / 9aea2c789

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