38 func (m *MemMapFs) getData() map[string]*mem.FileData { |
40 func (m *MemMapFs) getData() map[string]*mem.FileData { |
39 m.init.Do(func() { |
41 m.init.Do(func() { |
40 m.data = make(map[string]*mem.FileData) |
42 m.data = make(map[string]*mem.FileData) |
41 // Root should always exist, right? |
43 // Root should always exist, right? |
42 // TODO: what about windows? |
44 // TODO: what about windows? |
43 m.data[FilePathSeparator] = mem.CreateDir(FilePathSeparator) |
45 root := mem.CreateDir(FilePathSeparator) |
|
46 mem.SetMode(root, os.ModeDir|0755) |
|
47 m.data[FilePathSeparator] = root |
44 }) |
48 }) |
45 return m.data |
49 return m.data |
46 } |
50 } |
47 |
51 |
48 func (*MemMapFs) Name() string { return "MemMapFS" } |
52 func (*MemMapFs) Name() string { return "MemMapFS" } |
50 func (m *MemMapFs) Create(name string) (File, error) { |
54 func (m *MemMapFs) Create(name string) (File, error) { |
51 name = normalizePath(name) |
55 name = normalizePath(name) |
52 m.mu.Lock() |
56 m.mu.Lock() |
53 file := mem.CreateFile(name) |
57 file := mem.CreateFile(name) |
54 m.getData()[name] = file |
58 m.getData()[name] = file |
55 m.registerWithParent(file) |
59 m.registerWithParent(file, 0) |
56 m.mu.Unlock() |
60 m.mu.Unlock() |
57 return mem.NewFileHandle(file), nil |
61 return mem.NewFileHandle(file), nil |
58 } |
62 } |
59 |
63 |
60 func (m *MemMapFs) unRegisterWithParent(fileName string) error { |
64 func (m *MemMapFs) unRegisterWithParent(fileName string) error { |
81 return nil |
85 return nil |
82 } |
86 } |
83 return pfile |
87 return pfile |
84 } |
88 } |
85 |
89 |
86 func (m *MemMapFs) registerWithParent(f *mem.FileData) { |
90 func (m *MemMapFs) registerWithParent(f *mem.FileData, perm os.FileMode) { |
87 if f == nil { |
91 if f == nil { |
88 return |
92 return |
89 } |
93 } |
90 parent := m.findParent(f) |
94 parent := m.findParent(f) |
91 if parent == nil { |
95 if parent == nil { |
92 pdir := filepath.Dir(filepath.Clean(f.Name())) |
96 pdir := filepath.Dir(filepath.Clean(f.Name())) |
93 err := m.lockfreeMkdir(pdir, 0777) |
97 err := m.lockfreeMkdir(pdir, perm) |
94 if err != nil { |
98 if err != nil { |
95 //log.Println("Mkdir error:", err) |
99 //log.Println("Mkdir error:", err) |
96 return |
100 return |
97 } |
101 } |
98 parent, err = m.lockfreeOpen(pdir) |
102 parent, err = m.lockfreeOpen(pdir) |
117 if !i.IsDir() { |
121 if !i.IsDir() { |
118 return ErrFileExists |
122 return ErrFileExists |
119 } |
123 } |
120 } else { |
124 } else { |
121 item := mem.CreateDir(name) |
125 item := mem.CreateDir(name) |
|
126 mem.SetMode(item, os.ModeDir|perm) |
122 m.getData()[name] = item |
127 m.getData()[name] = item |
123 m.registerWithParent(item) |
128 m.registerWithParent(item, perm) |
124 } |
129 } |
125 return nil |
130 return nil |
126 } |
131 } |
127 |
132 |
128 func (m *MemMapFs) Mkdir(name string, perm os.FileMode) error { |
133 func (m *MemMapFs) Mkdir(name string, perm os.FileMode) error { |
|
134 perm &= chmodBits |
129 name = normalizePath(name) |
135 name = normalizePath(name) |
130 |
136 |
131 m.mu.RLock() |
137 m.mu.RLock() |
132 _, ok := m.getData()[name] |
138 _, ok := m.getData()[name] |
133 m.mu.RUnlock() |
139 m.mu.RUnlock() |
135 return &os.PathError{Op: "mkdir", Path: name, Err: ErrFileExists} |
141 return &os.PathError{Op: "mkdir", Path: name, Err: ErrFileExists} |
136 } |
142 } |
137 |
143 |
138 m.mu.Lock() |
144 m.mu.Lock() |
139 item := mem.CreateDir(name) |
145 item := mem.CreateDir(name) |
|
146 mem.SetMode(item, os.ModeDir|perm) |
140 m.getData()[name] = item |
147 m.getData()[name] = item |
141 m.registerWithParent(item) |
148 m.registerWithParent(item, perm) |
142 m.mu.Unlock() |
149 m.mu.Unlock() |
143 |
150 |
144 m.Chmod(name, perm|os.ModeDir) |
151 return m.setFileMode(name, perm|os.ModeDir) |
145 |
|
146 return nil |
|
147 } |
152 } |
148 |
153 |
149 func (m *MemMapFs) MkdirAll(path string, perm os.FileMode) error { |
154 func (m *MemMapFs) MkdirAll(path string, perm os.FileMode) error { |
150 err := m.Mkdir(path, perm) |
155 err := m.Mkdir(path, perm) |
151 if err != nil { |
156 if err != nil { |
208 return nil, ErrFileNotFound |
213 return nil, ErrFileNotFound |
209 } |
214 } |
210 } |
215 } |
211 |
216 |
212 func (m *MemMapFs) OpenFile(name string, flag int, perm os.FileMode) (File, error) { |
217 func (m *MemMapFs) OpenFile(name string, flag int, perm os.FileMode) (File, error) { |
|
218 perm &= chmodBits |
213 chmod := false |
219 chmod := false |
214 file, err := m.openWrite(name) |
220 file, err := m.openWrite(name) |
|
221 if err == nil && (flag&os.O_EXCL > 0) { |
|
222 return nil, &os.PathError{Op: "open", Path: name, Err: ErrFileExists} |
|
223 } |
215 if os.IsNotExist(err) && (flag&os.O_CREATE > 0) { |
224 if os.IsNotExist(err) && (flag&os.O_CREATE > 0) { |
216 file, err = m.Create(name) |
225 file, err = m.Create(name) |
217 chmod = true |
226 chmod = true |
218 } |
227 } |
219 if err != nil { |
228 if err != nil { |
297 m.unRegisterWithParent(oldname) |
306 m.unRegisterWithParent(oldname) |
298 fileData := m.getData()[oldname] |
307 fileData := m.getData()[oldname] |
299 delete(m.getData(), oldname) |
308 delete(m.getData(), oldname) |
300 mem.ChangeFileName(fileData, newname) |
309 mem.ChangeFileName(fileData, newname) |
301 m.getData()[newname] = fileData |
310 m.getData()[newname] = fileData |
302 m.registerWithParent(fileData) |
311 m.registerWithParent(fileData, 0) |
303 m.mu.Unlock() |
312 m.mu.Unlock() |
304 m.mu.RLock() |
313 m.mu.RLock() |
305 } else { |
314 } else { |
306 return &os.PathError{Op: "rename", Path: oldname, Err: ErrFileNotFound} |
315 return &os.PathError{Op: "rename", Path: oldname, Err: ErrFileNotFound} |
307 } |
316 } |
308 return nil |
317 return nil |
309 } |
318 } |
310 |
319 |
|
320 func (m *MemMapFs) LstatIfPossible(name string) (os.FileInfo, bool, error) { |
|
321 fileInfo, err := m.Stat(name) |
|
322 return fileInfo, false, err |
|
323 } |
|
324 |
311 func (m *MemMapFs) Stat(name string) (os.FileInfo, error) { |
325 func (m *MemMapFs) Stat(name string) (os.FileInfo, error) { |
312 f, err := m.Open(name) |
326 f, err := m.Open(name) |
313 if err != nil { |
327 if err != nil { |
314 return nil, err |
328 return nil, err |
315 } |
329 } |
316 fi := mem.GetFileInfo(f.(*mem.File).Data()) |
330 fi := mem.GetFileInfo(f.(*mem.File).Data()) |
317 return fi, nil |
331 return fi, nil |
318 } |
332 } |
319 |
333 |
320 func (m *MemMapFs) Chmod(name string, mode os.FileMode) error { |
334 func (m *MemMapFs) Chmod(name string, mode os.FileMode) error { |
321 name = normalizePath(name) |
335 mode &= chmodBits |
322 |
336 |
323 m.mu.RLock() |
337 m.mu.RLock() |
324 f, ok := m.getData()[name] |
338 f, ok := m.getData()[name] |
325 m.mu.RUnlock() |
339 m.mu.RUnlock() |
326 if !ok { |
340 if !ok { |
327 return &os.PathError{Op: "chmod", Path: name, Err: ErrFileNotFound} |
341 return &os.PathError{Op: "chmod", Path: name, Err: ErrFileNotFound} |
328 } |
342 } |
|
343 prevOtherBits := mem.GetFileInfo(f).Mode() & ^chmodBits |
|
344 |
|
345 mode = prevOtherBits | mode |
|
346 return m.setFileMode(name, mode) |
|
347 } |
|
348 |
|
349 func (m *MemMapFs) setFileMode(name string, mode os.FileMode) error { |
|
350 name = normalizePath(name) |
|
351 |
|
352 m.mu.RLock() |
|
353 f, ok := m.getData()[name] |
|
354 m.mu.RUnlock() |
|
355 if !ok { |
|
356 return &os.PathError{Op: "chmod", Path: name, Err: ErrFileNotFound} |
|
357 } |
329 |
358 |
330 m.mu.Lock() |
359 m.mu.Lock() |
331 mem.SetMode(f, mode) |
360 mem.SetMode(f, mode) |
332 m.mu.Unlock() |
361 m.mu.Unlock() |
|
362 |
|
363 return nil |
|
364 } |
|
365 |
|
366 func (m *MemMapFs) Chown(name string, uid, gid int) error { |
|
367 name = normalizePath(name) |
|
368 |
|
369 m.mu.RLock() |
|
370 f, ok := m.getData()[name] |
|
371 m.mu.RUnlock() |
|
372 if !ok { |
|
373 return &os.PathError{Op: "chown", Path: name, Err: ErrFileNotFound} |
|
374 } |
|
375 |
|
376 mem.SetUID(f, uid) |
|
377 mem.SetGID(f, gid) |
333 |
378 |
334 return nil |
379 return nil |
335 } |
380 } |
336 |
381 |
337 func (m *MemMapFs) Chtimes(name string, atime time.Time, mtime time.Time) error { |
382 func (m *MemMapFs) Chtimes(name string, atime time.Time, mtime time.Time) error { |