Fix memory clearing in adder
License: MIT Signed-off-by: Jeromy <jeromyj@gmail.com>
Jeromy committed
Dec 19, 2017 at 21:53 UTC
3e6eabba54c73964749f669d0f8b3ab12ae7bd7d
2 files changed
+32
-1
core/coreunix/add.go
+2
-1
@@ -443,9 +443,10 @@ func (adder *Adder) addFile(file files.File) error {
443
if err != nil {
444
return err
445
}
446
- if err := mr.Flush(); err != nil {
446
+ if err := mr.FlushMemFree(adder.ctx); err != nil {
447
return err
448
}
449
+
450
adder.liveNodes = 0
451
}
452
adder.liveNodes++
mfs/system.go
+30
@@ -123,6 +123,36 @@ func (kr *Root) Flush() error {
123
return nil
124
}
125
126
+// FlushMemFree flushes the root directory and then uncaches all of its links.
127
+// This has the effect of clearing out potentially stale references and allows
128
+// them to be garbage collected.
129
+// CAUTION: Take care not to ever call this while holding a reference to any
130
+// child directories. Those directories will be bad references and using them
131
+// may have unintended racy side effects.
132
+// A better implemented mfs system (one that does smarter internal caching and
133
+// refcounting) shouldnt need this method.
134
+func (kr *Root) FlushMemFree(ctx context.Context) error {
135
+ dir, ok := kr.GetValue().(*Directory)
136
+ if !ok {
137
+ return fmt.Errorf("invalid mfs structure, root should be a directory")
138
+ }
139
+
140
+ if err := dir.Flush(); err != nil {
141
+ return err
142
+ }
143
+
144
+ dir.lock.Lock()
145
+ defer dir.lock.Unlock()
146
+ for name := range dir.files {
147
+ delete(dir.files, name)
148
+ }
149
+ for name := range dir.childDirs {
150
+ delete(dir.childDirs, name)
151
+ }
152
+
153
+ return nil
154
+}
155
+
156
// closeChild implements the childCloser interface, and signals to the publisher that
157
// there are changes ready to be published
158
func (kr *Root) closeChild(name string, nd node.Node, sync bool) error {