import collections
from fusedir import sanitize_filename, Directory, CollectionDirectory, MagicDirectory, TagsDirectory, ProjectDirectory, SharedDirectory
-from fusefile import StreamReaderFile
+from fusefile import StreamReaderFile, StringFile
_logger = logging.getLogger('arvados.arvados_fuse')
self.dirobj.dec_use()
-class ObjectCache(object):
+class InodeCache(object):
def __init__(self, cap):
self._entries = collections.OrderedDict()
self._counter = itertools.count(1)
for key in ents:
capobj = self._entries[key]
if capobj.clear():
+ _logger.debug("Cleared %s", self._entries[key])
del self._entries[key]
def manage(self, obj):
obj._cache_priority = next(self._counter)
self._entries[obj._cache_priority] = obj
+ _logger.debug("Managing %s", obj)
self.cap_cache()
def touch(self, obj):
def unmanage(self, obj):
if obj._cache_priority in self._entries:
if obj.clear():
+ _logger.debug("Cleared %s", obj)
del self._entries[obj._cache_priority]
"""Manage the set of inodes. This is the mapping from a numeric id
to a concrete File or Directory object"""
- def __init__(self, cache_cap=1000):
+ def __init__(self, inode_cache=1000):
self._entries = {}
self._counter = itertools.count(llfuse.ROOT_INODE)
- self._obj_cache = ObjectCache(cap=cache_cap)
+ self._obj_cache = InodeCache(cap=inode_cache)
def __getitem__(self, item):
return self._entries[item]
return k in self._entries
def touch(self, entry):
+ entry._atime = time.time()
self._obj_cache.touch(entry)
def cap_cache(self):
"""
- def __init__(self, uid, gid, encoding="utf-8", cache_cap=1000):
+ def __init__(self, uid, gid, encoding="utf-8", inode_cache=1000):
super(Operations, self).__init__()
- self.inodes = Inodes(cache_cap)
+ self.inodes = Inodes(inode_cache)
self.uid = uid
self.gid = gid
self.encoding = encoding
fh = self._filehandles_counter
self._filehandles_counter += 1
self._filehandles[fh] = FileHandle(fh, p)
+ self.inodes.touch(p)
return fh
def read(self, fh, off, size):
else:
raise llfuse.FUSEError(errno.EBADF)
- # update atime
- handle.fileobj._atime = time.time()
+ self.inodes.touch(handle.fileobj)
try:
with llfuse.lock_released:
raise llfuse.FUSEError(errno.EIO)
# update atime
- p._atime = time.time()
+ self.inodes.touch(p)
- try:
- p.inc_use()
- self._filehandles[fh] = DirectoryHandle(fh, p, [('.', p), ('..', parent)] + list(p.items()))
- return fh
- finally:
- p.dec_use()
+ self._filehandles[fh] = DirectoryHandle(fh, p, [('.', p), ('..', parent)] + list(p.items()))
+ return fh
def readdir(self, fh, off):
parser.add_argument('--logfile', help="""Write debug logs and errors to the specified file (default stderr).""")
parser.add_argument('--foreground', action='store_true', help="""Run in foreground (default is to daemonize unless --exec specified)""", default=False)
parser.add_argument('--encoding', type=str, help="Character encoding to use for filesystem, default is utf-8 (see Python codec registry for list of available encodings)", default="utf-8")
+
+ parser.add_argument('--inode-cache', type=int, help="Inode cache size", default=1024)
+
parser.add_argument('--exec', type=str, nargs=argparse.REMAINDER,
dest="exec_args", metavar=('command', 'args', '...', '--'),
help="""Mount, run a command, then unmount and exit""")
try:
# Create the request handler
- operations = Operations(os.getuid(), os.getgid(), args.encoding)
+ operations = Operations(os.getuid(), os.getgid(), args.encoding, args.inode_cache)
api = ThreadSafeApiCache(arvados.config.settings())
usr = api.users().current().execute(num_retries=args.retries)
if dir_class is not None:
operations.inodes.add_entry(dir_class(*dir_args))
else:
- e = operations.inodes.add_entry(Directory(llfuse.ROOT_INODE))
+ e = operations.inodes.add_entry(Directory(llfuse.ROOT_INODE, operations.inodes))
dir_args[0] = e.inode
e._entries['by_id'] = operations.inodes.add_entry(MagicDirectory(*dir_args))
self.api = arvados.safeapi.ThreadSafeApiCache(arvados.config.settings())
def make_mount(self, root_class, **root_kwargs):
- operations = fuse.Operations(os.getuid(), os.getgid(), cache_cap=2)
+ operations = fuse.Operations(os.getuid(), os.getgid(), inode_cache=2)
operations.inodes.add_entry(root_class(
llfuse.ROOT_INODE, operations.inodes, self.api, 0, **root_kwargs))
llfuse.init(operations, self.mounttmp, [])