aboutsummaryrefslogtreecommitdiffstats
path: root/FuseArchive/FileSystem.py
diff options
context:
space:
mode:
Diffstat (limited to 'FuseArchive/FileSystem.py')
-rw-r--r--FuseArchive/FileSystem.py154
1 files changed, 154 insertions, 0 deletions
diff --git a/FuseArchive/FileSystem.py b/FuseArchive/FileSystem.py
new file mode 100644
index 0000000..dbdc8a3
--- /dev/null
+++ b/FuseArchive/FileSystem.py
@@ -0,0 +1,154 @@
+import fuse, os, logging, errno
+from ChunkFile import ChunkFile
+
+if not hasattr(fuse, '__version__'):
+ raise RuntimeError, \
+ "your fuse-py doesn't know of fuse.__version__, probably it's too old."
+
+fuse.fuse_python_api = (0, 2)
+fuse.feature_assert('stateful_files', 'has_init')
+
+class FileSystem(fuse.Fuse):
+
+ def __init__(self, *args, **kw):
+
+ fuse.Fuse.__init__(self, *args, **kw)
+ self.root = None
+
+ # Fix getattr and fgetattr to?
+ def getattr(self, path):
+ treefile = "./tree" + path
+
+ if os.path.isfile( treefile ):
+ logging.debug( "Delegating getattr to File for " + path )
+
+ # Check in the dirty cache first (to handle lseek and the
+ # relatively broken implmentation in fuse/python)
+ f = ChunkFile.get_dirty_file( path )
+ if f:
+ logging.info( "WORKAROUND: lseek appears to do a gettattr if whence is SEEK_END, using dirty cache object" )
+ stats = f.fgetattr()
+ # no release, it's still being used
+ else:
+ f = ChunkFile( path, os.O_RDONLY, 0 )
+ stats = f.fgetattr()
+ f.release( 0 )
+ else:
+ logging.debug( "Using os.lstat to get stats" )
+ stats = os.lstat( treefile )
+
+ return stats
+
+ def readlink(self, path):
+ return os.readlink("./tree" + path)
+
+ def readdir(self, path, offset):
+ for e in os.listdir("./tree" + path):
+ yield fuse.Direntry(e)
+
+ def unlink(self, path):
+ os.unlink("./tree" + path)
+
+ def rmdir(self, path):
+ os.rmdir("./tree" + path)
+
+ def symlink(self, path, path1):
+ os.symlink(path, "./tree" + path1)
+
+ def rename(self, path, path1):
+ os.rename("./tree" + path, "./tree" + path1)
+
+ def link(self, path, path1):
+ os.link("./tree" + path, "./tree" + path1)
+
+ def chmod(self, path, mode):
+ os.chmod("./tree" + path, mode)
+
+ def chown(self, path, user, group):
+ os.chown("./tree" + path, user, group)
+
+ def truncate(self, path, len):
+ # Truncate using the ftruncate on the file
+ logging.debug( "Using FuseArchiveFile to truncate %s to %d" % ( path, len) )
+ f = ChunkFile( path, os.O_RDWR, 0 )
+ f.ftruncate(len)
+ f.release( 0 )
+
+ def mknod(self, path, mode, dev):
+ os.mknod("./tree" + path, mode, dev)
+
+ def mkdir(self, path, mode):
+ os.mkdir("./tree" + path, mode)
+
+ def utime(self, path, times):
+ os.utime("./tree" + path, times)
+
+# The following utimens method would do the same as the above utime method.
+# We can't make it better though as the Python stdlib doesn't know of
+# subsecond preciseness in acces/modify times.
+#
+# def utimens(self, path, ts_acc, ts_mod):
+# os.utime("." + path, (ts_acc.tv_sec, ts_mod.tv_sec))
+
+ def access(self, path, mode):
+ if not os.access("./tree" + path, mode):
+ return -errno.EACCES
+
+# This is how we could add stub extended attribute handlers...
+# (We can't have ones which aptly delegate requests to the underlying fs
+# because Python lacks a standard xattr interface.)
+#
+# def getxattr(self, path, name, size):
+# val = name.swapcase() + '@' + path
+# if size == 0:
+# # We are asked for size of the value.
+# return len(val)
+# return val
+#
+# def listxattr(self, path, size):
+# # We use the "user" namespace to please XFS utils
+# aa = ["user." + a for a in ("foo", "bar")]
+# if size == 0:
+# # We are asked for size of the attr list, ie. joint size of attrs
+# # plus null separators.
+# return len("".join(aa)) + len(aa)
+# return aa
+
+ def statfs(self):
+ """
+ Should return an object with statvfs attributes (f_bsize, f_frsize...).
+ Eg., the return value of os.statvfs() is such a thing (since py 2.2).
+ If you are not reusing an existing statvfs object, start with
+ fuse.StatVFS(), and define the attributes.
+
+ To provide usable information (ie., you want sensible df(1)
+ output, you are suggested to specify the following attributes:
+
+ - f_bsize - preferred size of file blocks, in bytes
+ - f_frsize - fundamental size of file blcoks, in bytes
+ [if you have no idea, use the same as blocksize]
+ - f_blocks - total number of blocks in the filesystem
+ - f_bfree - number of free blocks
+ - f_files - total number of file inodes
+ - f_ffree - nunber of free file inodes
+ """
+
+ return os.statvfs(".")
+
+ def fsinit(self):
+ os.chdir(self.root)
+
+ def main(self, *a, **kw):
+
+ self.file_class = ChunkFile
+
+ # This is where fragments go
+ if not os.path.exists( 'storage' ):
+ os.mkdir( 'storage' )
+
+ # This is where the real files exist
+ if not os.path.exists( 'tree' ):
+ os.mkdir( 'tree' )
+
+ return fuse.Fuse.main(self, *a, **kw)
+