From bf0163c58bf83d1062786f83e3c6dff13ccb2c8f Mon Sep 17 00:00:00 2001 From: Xavier Lucas Date: Mon, 22 Feb 2016 13:31:57 +0100 Subject: [PATCH] Nil pointer derefrence on kernel dirent eviction Signed-off-by: Xavier Lucas --- svfs/directory.go | 75 ++++++++++++++++++++++------------------------- svfs/fs.go | 22 +++++--------- svfs/handle.go | 2 +- svfs/root.go | 16 +++++----- 4 files changed, 51 insertions(+), 64 deletions(-) diff --git a/svfs/directory.go b/svfs/directory.go index 871bdbe..ec69c18 100644 --- a/svfs/directory.go +++ b/svfs/directory.go @@ -14,9 +14,11 @@ import ( ) var ( - FolderRegex = regexp.MustCompile("^.+/$") - DirContentType = "application/directory" - ObjContentType = "application/octet-stream" + FolderRegex = regexp.MustCompile("^.+/$") + DirContentType = "application/directory" + ObjContentType = "application/octet-stream" + EntryCache = new(Cache) + DirectoryLister = new(DirLister) ) type DirLister struct { @@ -53,13 +55,11 @@ func (dl *DirLister) AddTask(o *Object, c chan<- *Object) { } type Directory struct { - apex bool - name string - path string - cache *Cache - s *swift.Connection - c *swift.Container - l *DirLister + apex bool + name string + path string + s *swift.Connection + c *swift.Container } func (d *Directory) Attr(ctx context.Context, a *fuse.Attr) error { @@ -102,7 +102,7 @@ func (d *Directory) Create(ctx context.Context, req *fuse.CreateRequest, resp *f } // Force cache eviction - d.cache.Delete(d.c.Name, d.path) + EntryCache.Delete(d.c.Name, d.path) return node, h, nil } @@ -117,12 +117,12 @@ func (d *Directory) Export() fuse.Dirent { func (d *Directory) ReadDirAll(ctx context.Context) (entries []fuse.Dirent, err error) { var ( dirs = make(map[string]bool) - loC = make(chan *Object, d.l.concurrency) + loC = make(chan *Object, DirectoryLister.concurrency) count = 0 ) // Cache check - if nodes := d.cache.Get(d.c.Name, d.path); nodes != nil { + if nodes := EntryCache.Get(d.c.Name, d.path); nodes != nil { for _, node := range nodes { entries = append(entries, node.Export()) } @@ -151,12 +151,10 @@ func (d *Directory) ReadDirAll(ctx context.Context) (entries []fuse.Dirent, err if o.ContentType == DirContentType && !FolderRegex.Match([]byte(o.Name)) { dirs[fileName] = true child = &Directory{ - s: d.s, - c: d.c, - l: d.l, - cache: d.cache, - path: o.Name + "/", - name: fileName, + s: d.s, + c: d.c, + path: o.Name + "/", + name: fileName, } } else if o.PseudoDirectory && FolderRegex.Match([]byte(o.Name)) && fileName != "" { @@ -165,12 +163,10 @@ func (d *Directory) ReadDirAll(ctx context.Context) (entries []fuse.Dirent, err if !dirs[realName] { dirs[realName] = true child = &Directory{ - s: d.s, - c: d.c, - l: d.l, - cache: d.cache, - path: o.Name, - name: realName, + s: d.s, + c: d.c, + path: o.Name, + name: realName, } } } else if !FolderRegex.Match([]byte(o.Name)) { @@ -187,7 +183,7 @@ func (d *Directory) ReadDirAll(ctx context.Context) (entries []fuse.Dirent, err if o.Bytes == 0 && !o.PseudoDirectory && o.ContentType != DirContentType { - d.l.AddTask(obj, loC) + DirectoryLister.AddTask(obj, loC) child = nil count++ } else { @@ -215,7 +211,7 @@ func (d *Directory) ReadDirAll(ctx context.Context) (entries []fuse.Dirent, err } } - d.cache.Set(d.c.Name, d.path, children) + EntryCache.Set(d.c.Name, d.path, children) return entries, nil } @@ -223,9 +219,9 @@ func (d *Directory) ReadDirAll(ctx context.Context) (entries []fuse.Dirent, err func (d *Directory) Lookup(ctx context.Context, req *fuse.LookupRequest, resp *fuse.LookupResponse) (fs.Node, error) { var nodes []Node - if nodes = d.cache.Get(d.c.Name, d.path); nodes == nil { + if nodes = EntryCache.Get(d.c.Name, d.path); nodes == nil { d.ReadDirAll(ctx) - nodes = d.cache.Get(d.c.Name, d.path) + nodes = EntryCache.Get(d.c.Name, d.path) } // Find matching child @@ -258,15 +254,14 @@ func (d *Directory) Mkdir(ctx context.Context, req *fuse.MkdirRequest) (fs.Node, } // Cache eviction - d.cache.Delete("", d.path) + EntryCache.Delete("", d.path) // Directory object return &Directory{ - name: req.Name, - path: absPath, - cache: d.cache, - s: d.s, - c: d.c, + name: req.Name, + path: absPath, + s: d.s, + c: d.c, }, nil } @@ -288,7 +283,7 @@ func (d *Directory) Remove(ctx context.Context, req *fuse.RemoveRequest) error { } // Cache eviction - d.cache.Delete(d.c.Name, d.path) + EntryCache.Delete(d.c.Name, d.path) return nil } @@ -301,14 +296,14 @@ func (d *Directory) Rename(ctx context.Context, req *fuse.RenameRequest, newDir // Swift move = copy + delete if t, ok := newDir.(*Container); ok { d.s.ObjectMove(d.c.Name, d.path+req.OldName, t.c.Name, t.path+req.NewName) - d.cache.Delete(d.c.Name, d.path) - t.cache.Delete(t.c.Name, t.path) + EntryCache.Delete(d.c.Name, d.path) + EntryCache.Delete(t.c.Name, t.path) return nil } if t, ok := newDir.(*Directory); ok { d.s.ObjectMove(d.c.Name, d.path+req.OldName, t.c.Name, t.path+req.NewName) - d.cache.Delete(d.c.Name, d.path) - t.cache.Delete(t.c.Name, t.path) + EntryCache.Delete(d.c.Name, d.path) + EntryCache.Delete(t.c.Name, t.path) return nil } return nil diff --git a/svfs/fs.go b/svfs/fs.go index 328b570..89abd2f 100644 --- a/svfs/fs.go +++ b/svfs/fs.go @@ -11,8 +11,6 @@ import ( // SVFS implements the Swift Virtual File System. type SVFS struct { s *swift.Connection - cache *Cache - lister *DirLister conf *Config concurrency uint64 } @@ -26,9 +24,9 @@ type Config struct { func (s *SVFS) Init(sc *swift.Connection, conf *Config, cconf *CacheConfig) error { s.s = sc s.conf = conf - s.cache = NewCache(cconf) s.s.ConnectTimeout = conf.ConnectTimeout - s.lister = &DirLister{ + EntryCache = NewCache(cconf) + DirectoryLister = &DirLister{ c: s.s, concurrency: conf.MaxReaddirConcurrency, } @@ -40,7 +38,7 @@ func (s *SVFS) Init(sc *swift.Connection, conf *Config, cconf *CacheConfig) erro } // Start directory lister - s.lister.Start() + DirectoryLister.Start() return nil } @@ -61,21 +59,17 @@ func (s *SVFS) Root() (fs.Node, error) { return &Container{ Directory: &Directory{ - apex: true, - cache: s.cache, - s: s.s, - c: &baseC, - l: s.lister, + apex: true, + s: s.s, + c: &baseC, }, cs: &segC, }, nil } return &Root{ Directory: &Directory{ - apex: true, - cache: s.cache, - s: s.s, - l: s.lister, + apex: true, + s: s.s, }, }, nil } diff --git a/svfs/handle.go b/svfs/handle.go index 2c8954e..c4952e8 100644 --- a/svfs/handle.go +++ b/svfs/handle.go @@ -40,7 +40,7 @@ func (fh *ObjectHandle) Release(ctx context.Context, req *fuse.ReleaseRequest) e fh.w.Close() } if fh.p != nil { - fh.p.cache.Delete("", fh.p.path) + EntryCache.Delete("", fh.p.path) } return nil } diff --git a/svfs/root.go b/svfs/root.go index e9c1f21..6dd225d 100644 --- a/svfs/root.go +++ b/svfs/root.go @@ -44,7 +44,7 @@ func (r *Root) ReadDirAll(ctx context.Context) (entries []fuse.Dirent, err error ) // Cache hit - if nodes := r.cache.Get("", r.path); nodes != nil { + if nodes := EntryCache.Get("", r.path); nodes != nil { for _, node := range nodes { entries = append(entries, node.Export()) } @@ -78,11 +78,9 @@ func (r *Root) ReadDirAll(ctx context.Context) (entries []fuse.Dirent, err error child := Container{ Directory: &Directory{ - s: r.s, - c: c, - l: r.l, - cache: r.cache, - name: name, + s: r.s, + c: c, + name: name, }, cs: segment, } @@ -91,7 +89,7 @@ func (r *Root) ReadDirAll(ctx context.Context) (entries []fuse.Dirent, err error entries = append(entries, child.Export()) } - r.cache.Set("", r.path, list) + EntryCache.Set("", r.path, list) return entries, nil } @@ -100,9 +98,9 @@ func (r *Root) Lookup(ctx context.Context, req *fuse.LookupRequest, resp *fuse.L var nodes []Node // Fill cache if expired - if nodes = r.cache.Get("", r.path); nodes == nil { + if nodes = EntryCache.Get("", r.path); nodes == nil { r.ReadDirAll(ctx) - nodes = r.cache.Get("", r.path) + nodes = EntryCache.Get("", r.path) } for _, item := range nodes {