作者:wrees
项目:cfs-binary-releas
func (f *fs) handleLookup(r *fuse.LookupRequest) {
log.Println("Inside handleLookup")
log.Printf("Running Lookup for %s", r.Name)
log.Println(r)
resp := &fuse.LookupResponse{}
l, err := f.rpc.api.Lookup(f.getContext(), &pb.LookupRequest{Name: r.Name, Parent: uint64(r.Node)})
if err != nil {
log.Fatalf("Lookup failed(%s): %v", r.Name, err)
}
// If there is no name then it wasn't found
if l.Name != r.Name {
log.Printf("ENOENT Lookup(%s)", r.Name)
r.RespondError(fuse.ENOENT)
return
}
resp.Node = fuse.NodeID(l.Attr.Inode)
copyAttr(&resp.Attr, l.Attr)
// TODO: should we make these configureable?
resp.Attr.Valid = 5 * time.Second
resp.EntryValid = 5 * time.Second
log.Println(resp)
r.Respond(resp)
}
作者:seacoastbo
项目:fus
func (c *serveConn) saveNode(inode uint64, node Node) (id fuse.NodeID, gen uint64) {
c.meta.Lock()
defer c.meta.Unlock()
var ref *NodeRef
if nodeRef, ok := node.(nodeRef); ok {
ref = nodeRef.nodeRef()
if ref.id != 0 {
// dropNode guarantees that NodeRef is zeroed at the same
// time as the NodeID is removed from serveConn.node, as
// guarded by c.meta; this means sn cannot be nil here
sn := c.node[ref.id]
sn.refs++
return ref.id, ref.generation
}
}
sn := &serveNode{inode: inode, node: node, refs: 1}
if n := len(c.freeNode); n > 0 {
id = c.freeNode[n-1]
c.freeNode = c.freeNode[:n-1]
c.node[id] = sn
c.nodeGen++
} else {
id = fuse.NodeID(len(c.node))
c.node = append(c.node, sn)
}
gen = c.nodeGen
if ref != nil {
ref.id = id
ref.generation = gen
}
return
}
作者:hatchlin
项目:fuse_gdriv
// Return a Dirent for all children of an inode, or ENOENT
func (sc *serveConn) lookup(req *fuse.LookupRequest) {
inode := uint64(req.Header.Node)
resp := &fuse.LookupResponse{}
var err error
file, err := sc.db.FileByInode(inode)
if err != nil {
fuse.Debug(fmt.Sprintf("FileByInode lookup failure for %d: %v", inode, err))
req.RespondError(fuse.ENOENT)
return
}
for _, cInode := range file.Children {
cf, err := sc.db.FileByInode(cInode)
if err != nil {
fuse.Debug(fmt.Sprintf("FileByInode(%v): %v", cInode, err))
req.RespondError(fuse.EIO)
return
}
if cf.Title == req.Name {
resp.Node = fuse.NodeID(cInode)
resp.EntryValid = *driveMetadataLatency
resp.Attr = sc.attrFromFile(*cf)
fuse.Debug(fmt.Sprintf("Lookup(%v in %v): %v", req.Name, inode, cInode))
req.Respond(resp)
return
}
}
fuse.Debug(fmt.Sprintf("Lookup(%v in %v): ENOENT", req.Name, inode))
req.RespondError(fuse.ENOENT)
}
作者:thingswis
项目:gocf
func (d Dir) Lookup(ctx context.Context, req *fuse.LookupRequest, res *fuse.LookupResponse) (fs.Node, error) {
log.Debug("Lookup(%s,%d,%s)", d.GetPath(), req.Node, req.Name)
lock.Lock()
defer lock.Unlock()
node, err := d.lookup(ctx, req.Name)
if err != nil {
return nil, err
}
res.Node = fuse.NodeID(d.Fs.GenerateInode(uint64(req.Node), req.Name))
return node, nil
}
作者:wrees
项目:cfs-binary-releas
func (f *fs) handleSymlink(r *fuse.SymlinkRequest) {
log.Println("Inside handleSymlink")
log.Println(r)
resp := &fuse.SymlinkResponse{}
symlink, err := f.rpc.api.Symlink(f.getContext(), &pb.SymlinkRequest{Parent: uint64(r.Node), Name: r.NewName, Target: r.Target, Uid: r.Uid, Gid: r.Gid})
if err != nil {
log.Fatalf("Symlink failed: %v", err)
}
resp.Node = fuse.NodeID(symlink.Attr.Inode)
copyAttr(&resp.Attr, symlink.Attr)
resp.Attr.Valid = 5 * time.Second
resp.EntryValid = 5 * time.Second
log.Println(resp)
r.Respond(resp)
}
作者:rsrsp
项目:fus
func (c *serveConn) saveNode(name string, node Node) (id fuse.NodeID, gen uint64, sn *serveNode) {
sn = &serveNode{name: name, node: node}
c.meta.Lock()
if n := len(c.freeNode); n > 0 {
id = c.freeNode[n-1]
c.freeNode = c.freeNode[:n-1]
c.node[id] = sn
c.nodeGen++
} else {
id = fuse.NodeID(len(c.node))
c.node = append(c.node, sn)
}
gen = c.nodeGen
c.meta.Unlock()
return
}
作者:wrees
项目:cfs-binary-releas
func (f *fs) handleCreate(r *fuse.CreateRequest) {
log.Println("Inside handleCreate")
log.Println(r)
resp := &fuse.CreateResponse{}
c, err := f.rpc.api.Create(f.getContext(), &pb.CreateRequest{Parent: uint64(r.Node), Name: r.Name, Attr: &pb.Attr{Uid: r.Uid, Gid: r.Gid, Mode: uint32(r.Mode)}})
if err != nil {
log.Fatalf("Failed to create file: %v", err)
}
resp.Node = fuse.NodeID(c.Attr.Inode)
copyAttr(&resp.Attr, c.Attr)
resp.EntryValid = 5 * time.Second
resp.Attr.Valid = 5 * time.Second
copyAttr(&resp.LookupResponse.Attr, c.Attr)
resp.LookupResponse.EntryValid = 5 * time.Second
resp.LookupResponse.Attr.Valid = 5 * time.Second
r.Respond(resp)
}
作者:slun
项目:Distributed-Storage-System
// Creates a regular file in dir with the attributes supplied in req
func (dir *Directory) Create(req *fuse.CreateRequest, resp *fuse.CreateResponse, intr fs.Intr) (fs.Node, fs.Handle, fuse.Error) {
if strings.Contains(req.Name, "@") {
return nil, nil, fuse.EPERM
}
filesystem.Lock(dir)
defer filesystem.Unlock(dir)
util.P_out(req.String())
rval := new(File)
rval.InitFile(req.Name, req.Mode, dir)
rval.Attrs.Gid = req.Gid
rval.Attrs.Uid = req.Uid
dir.setChild(rval)
resp.Attr = rval.Attr()
resp.Node = fuse.NodeID(rval.Attr().Inode)
rval.dirty = true
dir.dirty = true
return rval, rval, nil
}
作者:rfjako
项目:cluef
func (d *Dir) Lookup(ctx context.Context, req *fuse.LookupRequest, resp *fuse.LookupResponse) (fusefs.Node, error) {
if skipDirEntry(req.Name) {
return nil, fuse.ENOENT
}
path := filepath.Join(d.path, req.Name)
isDir := false
defer trace(NewLookupOp(req, path, isDir))
var st syscall.Stat_t
if err := syscall.Lstat(path, &st); err != nil {
return nil, fuse.ENOENT
}
resp.Attr = statToFuseAttr(st)
resp.Node = fuse.NodeID(resp.Attr.Inode)
// TODO: should we overwrite resp.EntryValid?
// resp.EntryValid = time.Duration(500) * time.Millisecond
if isDir = resp.Attr.Mode.IsDir(); isDir {
return NewDir(d.path, req.Name, d.fs), nil
}
return NewFile(d.path, req.Name, d.fs), nil
}
作者:justinburk
项目:fuse_gdriv
func (sc *serveConn) mkdir(req *fuse.MkdirRequest) {
if *readOnly {
req.RespondError(fuse.EPERM)
return
}
// TODO: if allow_other, require uid == invoking uid to allow writes
pInode := uint64(req.Header.Node)
pId, err := sc.db.FileIdForInode(pInode)
if err != nil {
debug.Printf("failed to get parent fileid: %v", err)
req.RespondError(fuse.EIO)
return
}
p := []*drive.ParentReference{&drive.ParentReference{Id: pId}}
file := &drive.File{Title: req.Name, MimeType: driveFolderMimeType, Parents: p}
file, err = sc.service.Files.Insert(file).Do()
if err != nil {
debug.Printf("Insert failed: %v", err)
req.RespondError(fuse.EIO)
return
}
debug.Printf("Child of %v created in drive: %+v", file.Parents[0].Id, file)
f, err := sc.db.UpdateFile(nil, file)
if err != nil {
debug.Printf("failed to update levelDB for %v: %v", f.Id, err)
// The write has happened to drive, but we failed to update the kernel.
// The Changes API will update Fuse, and when the kernel metadata for
// the parent directory expires, the new dir will become visible.
req.RespondError(fuse.EIO)
return
}
sc.db.FlushCachedInode(pInode)
resp := &fuse.MkdirResponse{}
resp.Node = fuse.NodeID(f.Inode)
resp.EntryValid = *driveMetadataLatency
resp.Attr.Valid = *driveMetadataLatency
resp.Attr = sc.attrFromFile(*f)
fuse.Debug(fmt.Sprintf("Mkdir(%v): %+v", req.Name, f))
req.Respond(resp)
}
作者:wrees
项目:cfs-binary-releas
func (f *fs) handleMkdir(r *fuse.MkdirRequest) {
log.Println("Inside handleMkdir")
log.Println(r)
resp := &fuse.MkdirResponse{}
m, err := f.rpc.api.MkDir(f.getContext(), &pb.MkDirRequest{Name: r.Name, Parent: uint64(r.Node), Attr: &pb.Attr{Uid: r.Uid, Gid: r.Gid, Mode: uint32(r.Mode)}})
if err != nil {
log.Fatalf("Mkdir failed(%s): %v", r.Name, err)
}
// If the name is empty, then the dir already exists
if m.Name != r.Name {
log.Printf("EEXIST Mkdir(%s)", r.Name)
r.RespondError(fuse.EEXIST)
return
}
resp.Node = fuse.NodeID(m.Attr.Inode)
copyAttr(&resp.Attr, m.Attr)
resp.Attr.Valid = 5 * time.Second
resp.EntryValid = 5 * time.Second
log.Println(resp)
r.Respond(resp)
}
作者:keybas
项目:kbfs-bet
func (c *Server) saveNode(inode uint64, node Node) (id fuse.NodeID, gen uint64) {
c.meta.Lock()
defer c.meta.Unlock()
if id, ok := c.nodeRef[node]; ok {
sn := c.node[id]
sn.refs++
return id, sn.generation
}
sn := &serveNode{inode: inode, node: node, refs: 1}
if n := len(c.freeNode); n > 0 {
id = c.freeNode[n-1]
c.freeNode = c.freeNode[:n-1]
c.node[id] = sn
c.nodeGen++
} else {
id = fuse.NodeID(len(c.node))
c.node = append(c.node, sn)
}
sn.generation = c.nodeGen
c.nodeRef[node] = id
return id, sn.generation
}
作者:AaronGoldma
项目:ccf
func (d dir) Lookup(name string, intr fs.Intr) (fs.Node, fuse.Error) {
log.Printf("Lookup %q in Directory: %q\n%v\n", name, d.name, d)
select {
case <-intr:
return nil, fuse.EINTR
default:
}
newNodeID := fuse.NodeID(fs.GenerateDynamicInode(uint64(d.inode), name))
switch d.contentType {
default:
return nil, nil
case "commit":
node, CommitErr := d.LookupCommit(name, intr, newNodeID)
return node, CommitErr
case "list":
node, listErr := d.LookupList(name, intr, newNodeID)
return node, listErr
case "tag":
node, tagErr := d.LookupTag(name, intr, newNodeID)
return node, tagErr
}
}
作者:AaronGoldma
项目:ccf
func generateInode(NodeID fuse.NodeID, name string) fuse.NodeID {
return fuse.NodeID(fs.GenerateDynamicInode(uint64(NodeID), name))
}
作者:hatchlin
项目:fuse_gdriv
// Create file in drive, allocate kernel filehandle for writes
func (sc *serveConn) create(req *fuse.CreateRequest) {
if *readOnly && !req.Flags.IsReadOnly() {
req.RespondError(fuse.EPERM)
return
}
pInode := uint64(req.Header.Node)
parent, err := sc.db.FileByInode(pInode)
if err != nil {
debug.Printf("failed to get parent file: %v", err)
req.RespondError(fuse.EIO)
return
}
p := &drive.ParentReference{Id: parent.Id}
f := &drive.File{Title: req.Name}
f.Parents = []*drive.ParentReference{p}
f, err = sc.service.Files.Insert(f).Do()
if err != nil {
debug.Printf("Files.Insert(f).Do(): %v", err)
req.RespondError(fuse.EIO)
return
}
inode, err := sc.db.InodeForFileId(f.Id)
if err != nil {
debug.Printf("failed creating inode for %v: %v", req.Name, err)
req.RespondError(fuse.EIO)
return
}
r, w := io.Pipe() // plumbing between WriteRequest and Drive
h := sc.allocHandle(fuse.NodeID(inode), w)
go sc.updateInDrive(f, r)
// Tell fuse and the OS about the file
df, err := sc.db.UpdateFile(nil, f)
if err != nil {
debug.Printf("failed to update levelDB for %v: %v", f.Id, err)
// The write has happened to drive, but we failed to update the kernel.
// The Changes API will update Fuse, and when the kernel metadata for
// the parent directory expires, the new file will become visible.
req.RespondError(fuse.EIO)
return
}
resp := fuse.CreateResponse{
// describes the opened handle
OpenResponse: fuse.OpenResponse{
Handle: fuse.HandleID(h),
Flags: fuse.OpenNonSeekable,
},
// describes the created file
LookupResponse: fuse.LookupResponse{
Node: fuse.NodeID(inode),
EntryValid: *driveMetadataLatency,
Attr: sc.attrFromFile(*df),
},
}
fuse.Debug(fmt.Sprintf("Create(%v in %v): %+v", req.Name, parent.Title, resp))
req.Respond(&resp)
}
作者:rsrsp
项目:fus
func (c *serveConn) serve(fs FS, r fuse.Request) {
intr := make(Intr)
req := &serveRequest{Request: r, Intr: intr}
fuse.Debugf("<- %s", req)
var node Node
var snode *serveNode
c.meta.Lock()
hdr := r.Hdr()
if id := hdr.Node; id != 0 {
if id < fuse.NodeID(len(c.node)) {
snode = c.node[uint(id)]
}
if snode == nil {
c.meta.Unlock()
println("missing node", id, len(c.node), snode)
fuse.Debugf("-> %#x %v", hdr.ID, fuse.ESTALE)
r.RespondError(fuse.ESTALE)
return
}
node = snode.node
}
if c.req[hdr.ID] != nil {
// This happens with OSXFUSE. Assume it's okay and
// that we'll never see an interrupt for this one.
// Otherwise everything wedges. TODO: Report to OSXFUSE?
intr = nil
} else {
c.req[hdr.ID] = req
}
c.meta.Unlock()
// Call this before responding.
// After responding is too late: we might get another request
// with the same ID and be very confused.
done := func(resp interface{}) {
fuse.Debugf("-> %#x %v", hdr.ID, resp)
c.meta.Lock()
c.req[hdr.ID] = nil
c.meta.Unlock()
}
switch r := r.(type) {
default:
// Note: To FUSE, ENOSYS means "this server never implements this request."
// It would be inappropriate to return ENOSYS for other operations in this
// switch that might only be unavailable in some contexts, not all.
done(fuse.ENOSYS)
r.RespondError(fuse.ENOSYS)
// FS operations.
case *fuse.InitRequest:
s := &fuse.InitResponse{
MaxWrite: 4096,
}
if fs, ok := fs.(FSIniter); ok {
if err := fs.Init(r, s, intr); err != nil {
done(err)
r.RespondError(err)
break
}
}
done(s)
r.Respond(s)
case *fuse.StatfsRequest:
s := &fuse.StatfsResponse{}
if fs, ok := fs.(FSStatfser); ok {
if err := fs.Statfs(r, s, intr); err != nil {
done(err)
r.RespondError(err)
break
}
}
done(s)
r.Respond(s)
// Node operations.
case *fuse.GetattrRequest:
s := &fuse.GetattrResponse{}
if n, ok := node.(NodeGetattrer); ok {
if err := n.Getattr(r, s, intr); err != nil {
done(err)
r.RespondError(err)
break
}
} else {
s.AttrValid = 1 * time.Minute
s.Attr = snode.attr()
}
done(s)
r.Respond(s)
case *fuse.SetattrRequest:
s := &fuse.SetattrResponse{}
// Special-case truncation, if no other bits are set
// and the open Handles all have a WriteAll method.
//
// TODO WriteAll mishandles all kinds of cases, e.g.
//.........这里部分代码省略.........
作者:keybas
项目:kbfs-bet
func (c *Server) serve(r fuse.Request) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
parentCtx := ctx
if c.context != nil {
ctx = c.context(ctx, r)
}
req := &serveRequest{Request: r, cancel: cancel}
c.debug(request{
Op: opName(r),
Request: r.Hdr(),
In: r,
})
var node Node
var snode *serveNode
c.meta.Lock()
hdr := r.Hdr()
if id := hdr.Node; id != 0 {
if id < fuse.NodeID(len(c.node)) {
snode = c.node[uint(id)]
}
if snode == nil {
c.meta.Unlock()
c.debug(response{
Op: opName(r),
Request: logResponseHeader{ID: hdr.ID},
Error: fuse.ESTALE.ErrnoName(),
// this is the only place that sets both Error and
// Out; not sure if i want to do that; might get rid
// of len(c.node) things altogether
Out: logMissingNode{
MaxNode: fuse.NodeID(len(c.node)),
},
})
r.RespondError(fuse.ESTALE)
return
}
node = snode.node
}
if c.req[hdr.ID] != nil {
// This happens with OSXFUSE. Assume it's okay and
// that we'll never see an interrupt for this one.
// Otherwise everything wedges. TODO: Report to OSXFUSE?
//
// TODO this might have been because of missing done() calls
} else {
c.req[hdr.ID] = req
}
c.meta.Unlock()
// Call this before responding.
// After responding is too late: we might get another request
// with the same ID and be very confused.
done := func(resp interface{}) {
msg := response{
Op: opName(r),
Request: logResponseHeader{ID: hdr.ID},
}
if err, ok := resp.(error); ok {
msg.Error = err.Error()
if ferr, ok := err.(fuse.ErrorNumber); ok {
errno := ferr.Errno()
msg.Errno = errno.ErrnoName()
if errno == err {
// it's just a fuse.Errno with no extra detail;
// skip the textual message for log readability
msg.Error = ""
}
} else {
msg.Errno = fuse.DefaultErrno.ErrnoName()
}
} else {
msg.Out = resp
}
c.debug(msg)
c.meta.Lock()
delete(c.req, hdr.ID)
c.meta.Unlock()
}
var responded bool
defer func() {
if rec := recover(); rec != nil {
const size = 1 << 16
buf := make([]byte, size)
n := runtime.Stack(buf, false)
buf = buf[:n]
log.Printf("fuse: panic in handler for %v: %v\n%s", r, rec, buf)
err := handlerPanickedError{
Request: r,
Err: rec,
}
done(err)
r.RespondError(err)
return
}
//.........这里部分代码省略.........
作者:seacoastbo
项目:fus
func (c *serveConn) serve(r fuse.Request) {
intr := make(Intr)
req := &serveRequest{Request: r, Intr: intr}
c.debug(request{
Op: opName(r),
Request: r.Hdr(),
In: r,
})
var node Node
var snode *serveNode
c.meta.Lock()
hdr := r.Hdr()
if id := hdr.Node; id != 0 {
if id < fuse.NodeID(len(c.node)) {
snode = c.node[uint(id)]
}
if snode == nil {
c.meta.Unlock()
c.debug(response{
Op: opName(r),
Request: logResponseHeader{ID: hdr.ID},
Error: fuse.ESTALE.ErrnoName(),
// this is the only place that sets both Error and
// Out; not sure if i want to do that; might get rid
// of len(c.node) things altogether
Out: logMissingNode{
MaxNode: fuse.NodeID(len(c.node)),
},
})
r.RespondError(fuse.ESTALE)
return
}
node = snode.node
}
if c.req[hdr.ID] != nil {
// This happens with OSXFUSE. Assume it's okay and
// that we'll never see an interrupt for this one.
// Otherwise everything wedges. TODO: Report to OSXFUSE?
//
// TODO this might have been because of missing done() calls
intr = nil
} else {
c.req[hdr.ID] = req
}
c.meta.Unlock()
// Call this before responding.
// After responding is too late: we might get another request
// with the same ID and be very confused.
done := func(resp interface{}) {
msg := response{
Op: opName(r),
Request: logResponseHeader{ID: hdr.ID},
}
if err, ok := resp.(error); ok {
msg.Error = err.Error()
if ferr, ok := err.(fuse.ErrorNumber); ok {
errno := ferr.Errno()
msg.Errno = errno.ErrnoName()
if errno == err {
// it's just a fuse.Errno with no extra detail;
// skip the textual message for log readability
msg.Error = ""
}
} else {
msg.Errno = fuse.DefaultErrno.ErrnoName()
}
} else {
msg.Out = resp
}
c.debug(msg)
c.meta.Lock()
delete(c.req, hdr.ID)
c.meta.Unlock()
}
switch r := r.(type) {
default:
// Note: To FUSE, ENOSYS means "this server never implements this request."
// It would be inappropriate to return ENOSYS for other operations in this
// switch that might only be unavailable in some contexts, not all.
done(fuse.ENOSYS)
r.RespondError(fuse.ENOSYS)
// FS operations.
case *fuse.InitRequest:
s := &fuse.InitResponse{
MaxWrite: 128 * 1024,
Flags: fuse.InitBigWrites,
}
if fs, ok := c.fs.(FSIniter); ok {
if err := fs.Init(r, s, intr); err != nil {
done(err)
r.RespondError(err)
break
}
}
done(s)
//.........这里部分代码省略.........
作者:AaronGoldma
项目:ccf
func (d dir) LookupCommit(name string, intr fs.Intr, nodeID fuse.NodeID) (fs.Node, fuse.Error) {
select {
case <-intr:
return nil, fuse.EINTR
default:
}
ino := fuse.NodeID(1)
if d.parent != nil {
ino = generateInode(d.parent.inode, name)
}
c, CommitErr := services.GetCommit(d.leaf.(objects.HKID))
if CommitErr != nil {
return nil, fuse.EIO
/*
log.Printf("commit %s:", CommitErr)
_, err := services.GetKey(d.leaf.(objects.HKID))
perm := os.FileMode(0555)
if err == nil {
perm = 0777
}
return dir{
permission: perm,
contentType: "commit",
leaf: d.leaf.(objects.HKID),
parent: &d,
name: name,
openHandles: map[string]bool{},
inode: ino,
}, nil
*/
}
//get list hash
l, listErr := services.GetList(c.ListHash) //l is the list object
if listErr != nil {
log.Printf("commit list retrieval error %s:", listErr)
return nil, nil
}
listEntry, present := l[name] //go through list entries and is it maps to the string you passed in present == 1
if !present {
return nil, fuse.ENOENT
}
//getKey to figure out permissions of the child
_, keyErr := services.GetKey(c.Hkid)
//perm := fuse.Attr{Mode: 0555}//default read permissions
perm := os.FileMode(0777)
if keyErr != nil {
log.Printf("error not nil; change file Mode %s:", keyErr)
//perm = fuse.Attr{Mode: 0755}
perm = os.FileMode(0555)
}
if listEntry.TypeString == "blob" {
b, blobErr := services.GetBlob(listEntry.Hash.(objects.HCID))
sizeBlob := 0
if blobErr == nil {
sizeBlob = len(b)
}
return file{
contentHash: listEntry.Hash.(objects.HCID),
permission: perm,
name: name,
parent: &d,
inode: nodeID,
size: uint64(sizeBlob),
}, nil
}
ino = fuse.NodeID(1)
if d.parent != nil {
ino = generateInode(d.parent.inode, name)
}
return dir{
leaf: listEntry.Hash,
permission: perm,
contentType: listEntry.TypeString,
parent: &d,
name: name,
openHandles: map[string]*openFileHandle{},
inode: ino,
}, nil
}