Beispiel #1
0
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)
}
Beispiel #2
0
// 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)
}