// Pass sequential writes on to the correct handle for uploading func (sc *serveConn) write(req *fuse.WriteRequest) { if *readOnly { req.RespondError(fuse.EPERM) return } // TODO: if allow_other, require uid == invoking uid to allow writes h, err := sc.handleById(req.Handle) if err != nil { fuse.Debug(fmt.Sprintf("inodeByNodeID(%v): %v", req.Handle, err)) req.RespondError(fuse.ESTALE) return } if h.lastByte != req.Offset { fuse.Debug(fmt.Sprintf("non-sequential write: got %v, expected %v", req.Offset, h.lastByte)) req.RespondError(fuse.EIO) return } n, err := h.writer.Write(req.Data) if err != nil { req.RespondError(fuse.EIO) return } sc.Lock() h.lastByte += int64(n) sc.handles[req.Handle] = h sc.Unlock() req.Respond(&fuse.WriteResponse{n}) }
func (f *fs) handleWrite(r *fuse.WriteRequest) { log.Println("Inside handleWrite") log.Printf("Writing %d bytes at offset %d", len(r.Data), r.Offset) log.Println(r) // TODO: Implement write // Currently this is stupid simple and doesn't handle all the possibilities resp := &fuse.WriteResponse{} w, err := f.rpc.api.Write(f.getContext(), &pb.WriteRequest{Inode: uint64(r.Node), Offset: r.Offset, Payload: r.Data}) if err != nil { log.Fatalf("Write to file failed: %v", err) } if w.Status != 0 { log.Printf("Write status non zero(%d)\n", w.Status) } resp.Size = len(r.Data) r.Respond(resp) }
// Copies data from req.Data to the File's data array beginning at index req.Offset. // Grows file.data if necessary. func (file *File) Write(req *fuse.WriteRequest, resp *fuse.WriteResponse, intr fs.Intr) fuse.Error { filesystem.Lock(file) defer filesystem.Unlock(file) util.P_out(req.String()) writeSize := len(req.Data) size := uint64(req.Offset) + uint64(writeSize) if size < file.Attr().Size { size = file.Attr().Size } if size > uint64(cap(file.data)) { tmp := file.data file.data = make([]byte, size, size*2) copy(file.data, tmp) } else { file.data = file.data[:size] } copy(file.data[req.Offset:], req.Data) resp.Size = writeSize file.Attrs.Size = uint64(size) file.Attrs.Mtime = time.Now() file.dirty = true return nil }