tahoe-lafs/contrib/fuse/impl_b/pyfuse/memoryfs.py

156 lines
4.6 KiB
Python

from kernel import *
from handler import Handler
import stat, time, os, weakref, errno
from cStringIO import StringIO
class MemoryFS(object):
INFINITE = 86400.0
class Dir(object):
type = TYPE_DIR
def __init__(self, attr):
self.attr = attr
self.contents = {} # { 'filename': Dir()/File()/SymLink() }
class File(object):
type = TYPE_REG
def __init__(self, attr):
self.attr = attr
self.data = StringIO()
class SymLink(object):
type = TYPE_LNK
def __init__(self, attr, target):
self.attr = attr
self.target = target
def __init__(self, root=None):
self.uid = os.getuid()
self.gid = os.getgid()
self.umask = os.umask(0); os.umask(self.umask)
self.root = root or self.Dir(self.newattr(stat.S_IFDIR))
self.root.id = FUSE_ROOT_ID
self.nodes = weakref.WeakValueDictionary()
self.nodes[FUSE_ROOT_ID] = self.root
self.nextid = FUSE_ROOT_ID + 1
def newattr(self, s, ino=None, mode=0666):
now = time.time()
attr = fuse_attr(size = 0,
mode = s | (mode & ~self.umask),
nlink = 1, # even on dirs! this confuses 'find' in
# a good way :-)
atime = now,
mtime = now,
ctime = now,
uid = self.uid,
gid = self.gid)
if ino is None:
ino = id(attr)
if ino < 0:
ino = ~ino
attr.ino = ino
return attr
def getnode(self, id):
return self.nodes[id]
def modified(self, node):
node.attr.mtime = node.attr.atime = time.time()
if isinstance(node, self.File):
node.data.seek(0, 2)
node.attr.size = node.data.tell()
def getattr(self, node):
return node.attr, self.INFINITE
def setattr(self, node, mode, uid, gid, size, atime, mtime):
if mode is not None:
node.attr.mode = (node.attr.mode & ~0777) | (mode & 0777)
if uid is not None:
node.attr.uid = uid
if gid is not None:
node.attr.gid = gid
if size is not None:
assert isinstance(node, self.File)
node.data.seek(0, 2)
oldsize = node.data.tell()
if size < oldsize:
node.data.seek(size)
node.data.truncate()
self.modified(node)
elif size > oldsize:
node.data.write('\x00' * (size - oldsize))
self.modified(node)
if atime is not None:
node.attr.atime = atime
if mtime is not None:
node.attr.mtime = mtime
def listdir(self, node):
assert isinstance(node, self.Dir)
for name, subobj in node.contents.items():
yield name, subobj.type
def lookup(self, dirnode, filename):
try:
return dirnode.contents[filename].id, self.INFINITE
except KeyError:
raise IOError(errno.ENOENT, filename)
def open(self, filenode, flags):
return filenode.data
def newnodeid(self, newnode):
id = self.nextid
self.nextid += 1
newnode.id = id
self.nodes[id] = newnode
return id
def mknod(self, dirnode, filename, mode):
node = self.File(self.newattr(stat.S_IFREG, mode=mode))
dirnode.contents[filename] = node
return self.newnodeid(node), self.INFINITE
def mkdir(self, dirnode, subdirname, mode):
node = self.Dir(self.newattr(stat.S_IFDIR, mode=mode))
dirnode.contents[subdirname] = node
return self.newnodeid(node), self.INFINITE
def symlink(self, dirnode, linkname, target):
node = self.SymLink(self.newattr(stat.S_IFLNK), target)
dirnode.contents[linkname] = node
return self.newnodeid(node), self.INFINITE
def unlink(self, dirnode, filename):
del dirnode.contents[filename]
rmdir = unlink
def readlink(self, symlinknode):
return symlinknode.target
def rename(self, olddirnode, oldname, newdirnode, newname):
node = olddirnode.contents[oldname]
newdirnode.contents[newname] = node
del olddirnode.contents[oldname]
def getxattrs(self, node):
try:
return node.xattrs
except AttributeError:
node.xattrs = {}
return node.xattrs
if __name__ == '__main__':
import sys
mountpoint = sys.argv[1]
memoryfs = MemoryFS()
handler = Handler(mountpoint, memoryfs)
handler.loop_forever()