Example #1
0
func (f *fs) handleRename(r *fuse.RenameRequest) {
	log.Println("Inside handleRename")
	log.Println(r)
	_, err := f.rpc.api.Rename(f.getContext(), &pb.RenameRequest{OldParent: uint64(r.Node), NewParent: uint64(r.NewDir), OldName: r.OldName, NewName: r.NewName})
	if err != nil {
		log.Fatalf("Rename failed: %v", err)
	}
	r.Respond()
}
// Moves a file from dir to newDir (potentially the same as dir) and changes its name from req.OldName
// to req.NewName
func (dir *Directory) Rename(req *fuse.RenameRequest, newDir fs.Node, intr fs.Intr) fuse.Error {
	filesystem.Lock(dir)
	defer filesystem.Unlock(dir)
	util.P_out(req.String())
	if d, newDirOk := newDir.(*Directory); newDirOk {
		if v, oldNameInDir := dir.children[req.OldName]; oldNameInDir {
			v.setName(req.NewName)
			d.setChild(v)
			if file, ok := v.(*File); ok {
				file.dirty = true
				file.parent = d
			}
			dir.removeChild(req.OldName)
			d.dirty = true
			dir.dirty = true
			return nil
		}
		return fuse.ENOENT
	}
	return fuse.Errno(syscall.ENOTDIR)
}
Example #3
0
// rename renames a file or directory, optionally reparenting it
func (sc *serveConn) rename(req *fuse.RenameRequest) {
	if *readOnly {
		debug.Printf("attempt to rename while fs in readonly mode")
		req.RespondError(fuse.EPERM)
		return
	}
	// TODO: if allow_other, require uid == invoking uid to allow writes
	oldParent, err := sc.db.FileByInode(uint64(req.Header.Node))
	if err != nil {
		debug.Printf("can't find the referenced inode: %v", req.Header.Node)
		req.RespondError(fuse.ENOENT)
		return
	}
	var f *drive_db.File
	for _, i := range oldParent.Children {
		c, err := sc.db.FileByInode(uint64(i))
		if err != nil {
			debug.Printf("error iterating child inodes: %v", err)
			continue
		}
		if c.Title == req.OldName {
			f = c
		}
	}
	if f == nil {
		debug.Printf("can't find the old file '%v' in '%v'", req.OldName, oldParent.Title)
		req.RespondError(fuse.ENOENT)
		return
	}

	newParent, err := sc.db.FileByInode(uint64(req.NewDir))
	if err != nil {
		debug.Printf("can't find the new parent by inode: %v", req.NewDir)
		req.RespondError(fuse.ENOENT)
		return
	}

	// did the name change?
	if req.OldName != req.NewName {
		f.Title = req.NewName
	}

	// did the parent change?
	var sameParent bool
	var numParents int
	var oldParentId string
	for _, o := range f.Parents {
		numParents++
		oldParentId = o.Id
		if o.Id == newParent.Id {
			sameParent = true
		}
	}
	if !sameParent && numParents > 1 {
		// TODO: Figure out how to identify which of the multiple parents the
		// file is being moved from, so we can call RemoveParents() correctly
		debug.Printf("can't reparent file with multiple parents: %v", req.OldName)
		req.RespondError(fuse.ENOSYS)
		return
	}

	u := sc.service.Files.Update(f.Id, f.File)
	if !sameParent {
		debug.Printf("moving from %v to %v", oldParentId, newParent.Id)
		u = u.AddParents(newParent.Id)
		u = u.RemoveParents(oldParentId)
	}
	r, err := u.Do()
	if err != nil {
		debug.Printf("failed to update '%v' in drive: %v", req.OldName, err)
		req.RespondError(fuse.EIO)
		return
	}

	if _, err := sc.db.UpdateFile(nil, r); err != nil {
		debug.Printf("failed to update leveldb and cache: ", err)
		req.RespondError(fuse.EIO)
		return
	}
	debug.Printf("rename complete")
	req.Respond()
	return
}