Esempio n. 1
0
func (me *UnionFs) Promote(name string, srcResult branchResult, context *fuse.Context) (code fuse.Status) {
	writable := me.fileSystems[0]
	sourceFs := me.fileSystems[srcResult.branch]

	// Promote directories.
	me.promoteDirsTo(name)

	if srcResult.attr.IsRegular() {
		code = fuse.CopyFile(sourceFs, writable, name, name, context)
	} else if srcResult.attr.IsSymlink() {
		link := ""
		link, code = sourceFs.Readlink(name, context)
		if !code.Ok() {
			log.Println("can't read link in source fs", name)
		} else {
			code = writable.Symlink(link, name, context)
		}
	} else if srcResult.attr.IsDirectory() {
		code = writable.Mkdir(name, 0755, context)
	} else {
		log.Println("Unknown file type:", srcResult.attr)
		return fuse.ENOSYS
	}

	if !code.Ok() {
		me.branchCache.GetFresh(name)
		return code
	} else {
		r := me.getBranch(name)
		r.branch = 0
		me.branchCache.Set(name, r)
	}

	return fuse.OK
}
Esempio n. 2
0
func (me *UnionFs) Promote(name string, srcResult branchResult) fuse.Status {
	if !srcResult.attr.IsRegular() {
		// TODO - implement rename for dirs, links, etc.
		log.Println("Can only promote normal files: ", name, srcResult.attr)
		return fuse.ENOSYS
	}

	writable := me.fileSystems[0]
	sourceFs := me.fileSystems[srcResult.branch]

	// Promote directories.
	me.promoteDirsTo(name)

	code := fuse.CopyFile(sourceFs, writable, name, name)
	if !code.Ok() {
		me.branchCache.GetFresh(name)
		return code
	} else {
		r := me.getBranch(name)
		r.branch = 0
		me.branchCache.Set(name, r)
	}

	return fuse.OK
}
Esempio n. 3
0
func (me *UnionFs) Promote(name string, srcResult branchResult, context *fuse.Context) (code fuse.Status) {
	writable := me.fileSystems[0]
	sourceFs := me.fileSystems[srcResult.branch]

	// Promote directories.
	me.promoteDirsTo(name)

	if srcResult.attr.IsRegular() {
		code = fuse.CopyFile(sourceFs, writable, name, name, context)
		files := me.nodeFs.AllFiles(name, 0)
		for _, f := range files {
			if !code.Ok() {
				break
			}
			uf := f.File.(*UnionFsFile)
			if uf.layer > 0 {
				uf.layer = 0
				uf.File.Release()
				uf.File, code = me.fileSystems[0].Open(name, f.OpenFlags, context)
			}
		}
	} else if srcResult.attr.IsSymlink() {
		link := ""
		link, code = sourceFs.Readlink(name, context)
		if !code.Ok() {
			log.Println("can't read link in source fs", name)
		} else {
			code = writable.Symlink(link, name, context)
		}
	} else if srcResult.attr.IsDirectory() {
		code = writable.Mkdir(name, 0755, context)
	} else {
		log.Println("Unknown file type:", srcResult.attr)
		return fuse.ENOSYS
	}

	if !code.Ok() {
		me.branchCache.GetFresh(name)
		return code
	} else {
		r := me.getBranch(name)
		r.branch = 0
		me.branchCache.Set(name, r)
	}

	return fuse.OK
}
Esempio n. 4
0
// Must run inside mutex.
func (me *memNode) promote() {
	if me.backing == "" {
		me.backing = me.fs.getFilename()
		destfs := &fuse.LoopbackFileSystem{Root: "/"}
		fuse.CopyFile(me.fs.readonly, destfs,
			me.original, strings.TrimLeft(me.backing, "/"), nil)
		me.original = ""
		files := me.Inode().Files(0)
		for _, f := range files {
			mf := f.File.(*memNodeFile)
			inner := mf.File
			osFile, err := os.Open(me.backing)
			if err != nil {
				panic("error opening backing file")
			}
			mf.File = &fuse.LoopbackFile{File: osFile}
			inner.Flush()
			inner.Release()
		}
	}
}
Esempio n. 5
0
func (me *UnionFs) Promote(name string, srcResult branchResult, context *fuse.Context) (code fuse.Status) {
	writable := me.fileSystems[0]
	sourceFs := me.fileSystems[srcResult.branch]

	// Promote directories.
	me.promoteDirsTo(name)

	if srcResult.attr.IsRegular() {
		code = fuse.CopyFile(sourceFs, writable, name, name, context)

		if code.Ok() {
			code = writable.Chmod(name, srcResult.attr.Mode&07777|0200, context)
		}
		if code.Ok() {
			code = writable.Utimens(name, srcResult.attr.Atimens(),
				srcResult.attr.Mtimens(), context)
		}

		files := me.nodeFs.AllFiles(name, 0)
		for _, fileWrapper := range files {
			if !code.Ok() {
				break
			}
			var uf *unionFsFile
			f := fileWrapper.File
			for f != nil {
				ok := false
				uf, ok = f.(*unionFsFile)
				if ok {
					break
				}
				f = f.InnerFile()
			}
			if uf == nil {
				panic("no unionFsFile found inside")
			}

			if uf.layer > 0 {
				uf.layer = 0
				f := uf.File
				uf.File, code = me.fileSystems[0].Open(name, fileWrapper.OpenFlags, context)
				f.Flush()
				f.Release()
			}
		}
	} else if srcResult.attr.IsSymlink() {
		link := ""
		link, code = sourceFs.Readlink(name, context)
		if !code.Ok() {
			log.Println("can't read link in source fs", name)
		} else {
			code = writable.Symlink(link, name, context)
		}
	} else if srcResult.attr.IsDir() {
		code = writable.Mkdir(name, srcResult.attr.Mode&07777|0200, context)
	} else {
		log.Println("Unknown file type:", srcResult.attr)
		return fuse.ENOSYS
	}

	if !code.Ok() {
		me.branchCache.GetFresh(name)
		return code
	} else {
		r := me.getBranch(name)
		r.branch = 0
		me.branchCache.Set(name, r)
	}

	return fuse.OK
}