From 7f85e159906a4356ae23a8d72f8893469efb5407 Mon Sep 17 00:00:00 2001 From: sparklxb Date: Fri, 10 Mar 2017 10:28:07 +0800 Subject: [PATCH] complement weed mount --- weed/command/mount_std.go | 64 +++++++++++++++--------- weed/server/filer_server.go | 1 + weed/server/filer_server_handlers_api.go | 40 +++++++++++++++ 3 files changed, 81 insertions(+), 24 deletions(-) create mode 100644 weed/server/filer_server_handlers_api.go diff --git a/weed/command/mount_std.go b/weed/command/mount_std.go index ec990adae..bd3b6a490 100644 --- a/weed/command/mount_std.go +++ b/weed/command/mount_std.go @@ -7,6 +7,8 @@ import ( "os" "runtime" + "path" + "bazil.org/fuse" "bazil.org/fuse/fs" "github.com/chrislusf/seaweedfs/weed/filer" @@ -23,7 +25,7 @@ func runMount(cmd *Command, args []string) bool { return false } - c, err := fuse.Mount(*mountOptions.dir) + c, err := fuse.Mount(*mountOptions.dir, fuse.LocalVolume()) if err != nil { glog.Fatal(err) return false @@ -51,61 +53,75 @@ func runMount(cmd *Command, args []string) bool { type WFS struct{} func (WFS) Root() (fs.Node, error) { - return Dir{}, nil + return &Dir{Path: "/"}, nil } type Dir struct { - Path string - Id uint64 + Id uint64 + Path string + DirentMap map[string]*fuse.Dirent } -func (dir Dir) Attr(context context.Context, attr *fuse.Attr) error { - attr.Inode = 1 +func (dir *Dir) Attr(context context.Context, attr *fuse.Attr) error { + attr.Inode = dir.Id attr.Mode = os.ModeDir | 0555 return nil } -func (dir Dir) Lookup(ctx context.Context, name string) (fs.Node, error) { - files_result, e := filer.ListFiles(*mountOptions.filer, dir.Path, name) - if e != nil { - return nil, fuse.ENOENT +func (dir *Dir) Lookup(ctx context.Context, name string) (fs.Node, error) { + if dirent, ok := dir.DirentMap[name]; ok { + if dirent.Type == fuse.DT_File { + return &File{dirent.Inode, dirent.Name}, nil + } + return &Dir{ + Id: dirent.Inode, + Path: path.Join(dir.Path, dirent.Name), + }, nil } - if len(files_result.Files) > 0 { - return File{files_result.Files[0].Id, files_result.Files[0].Name}, nil - } - return nil, fmt.Errorf("File Not Found for %s", name) + return nil, fuse.ENOENT } -func (dir Dir) ReadDirAll(ctx context.Context) ([]fuse.Dirent, error) { +func (dir *Dir) ReadDirAll(ctx context.Context) ([]fuse.Dirent, error) { var ret []fuse.Dirent + if dir.DirentMap == nil { + dir.DirentMap = make(map[string]*fuse.Dirent) + } if dirs, e := filer.ListDirectories(*mountOptions.filer, dir.Path); e == nil { for _, d := range dirs.Directories { dirId := uint64(d.Id) - ret = append(ret, fuse.Dirent{Inode: dirId, Name: d.Name, Type: fuse.DT_Dir}) + dirent := fuse.Dirent{Inode: dirId, Name: d.Name, Type: fuse.DT_Dir} + ret = append(ret, dirent) + dir.DirentMap[d.Name] = &dirent } } if files, e := filer.ListFiles(*mountOptions.filer, dir.Path, ""); e == nil { for _, f := range files.Files { if fileId, e := storage.ParseFileId(string(f.Id)); e == nil { fileInode := uint64(fileId.VolumeId)<<48 + fileId.Key - ret = append(ret, fuse.Dirent{Inode: fileInode, Name: f.Name, Type: fuse.DT_File}) + dirent := fuse.Dirent{Inode: fileInode, Name: f.Name, Type: fuse.DT_File} + ret = append(ret, dirent) + dir.DirentMap[f.Name] = &dirent } - } } return ret, nil } +const greeting = "hello, world\n" + type File struct { - FileId filer.FileId - Name string + Id uint64 + // FileId filer.FileId + Name string } -func (File) Attr(context context.Context, attr *fuse.Attr) error { - attr.Inode = 2 +func (file *File) Attr(context context.Context, attr *fuse.Attr) error { + attr.Inode = file.Id attr.Mode = 0444 + attr.Size = uint64(len(greeting)) return nil } -func (File) ReadAll(ctx context.Context) ([]byte, error) { - return []byte("hello, world\n"), nil + +func (file *File) ReadAll(ctx context.Context) ([]byte, error) { + return []byte(greeting), nil } diff --git a/weed/server/filer_server.go b/weed/server/filer_server.go index 0601effed..33b3677a5 100644 --- a/weed/server/filer_server.go +++ b/weed/server/filer_server.go @@ -107,6 +107,7 @@ func NewFilerServer(r *http.ServeMux, ip string, port int, master string, dir st r.HandleFunc("/admin/mv", fs.moveHandler) r.HandleFunc("/admin/register", fs.registerHandler) + r.HandleFunc("/__api__", fs.apiHandler) } r.HandleFunc("/", fs.filerHandler) diff --git a/weed/server/filer_server_handlers_api.go b/weed/server/filer_server_handlers_api.go new file mode 100644 index 000000000..fe82827f4 --- /dev/null +++ b/weed/server/filer_server_handlers_api.go @@ -0,0 +1,40 @@ +package weed_server + +import ( + "encoding/json" + "net/http" + + "github.com/chrislusf/seaweedfs/weed/filer" + "github.com/chrislusf/seaweedfs/weed/glog" +) + +func (fs *FilerServer) apiHandler(w http.ResponseWriter, r *http.Request) { + request := r.FormValue("request") + apiRequest := filer.ApiRequest{} + + err := json.Unmarshal([]byte(request), &apiRequest) + if err != nil { + glog.V(0).Infoln("failing to read request", r.RequestURI, request) + writeJsonError(w, r, http.StatusInternalServerError, err) + } + switch apiRequest.Command { + case "listDirectories": + res := filer.ListDirectoriesResult{} + res.Directories, err = fs.filer.ListDirectories(apiRequest.Directory) + if err != nil { + res.Error = err.Error() + } + writeJsonQuiet(w, r, http.StatusOK, res) + case "listFiles": + res := filer.ListFilesResult{} + limit := 1 + if len(apiRequest.FileName) == 0 { + limit = 100 + } + res.Files, err = fs.filer.ListFiles(apiRequest.Directory, apiRequest.FileName, limit) + if err != nil { + res.Error = err.Error() + } + writeJsonQuiet(w, r, http.StatusOK, res) + } +}