3198: Fixed arv-mount for refactoring.
authorPeter Amstutz <peter.amstutz@curoverse.com>
Mon, 13 Apr 2015 21:08:42 +0000 (17:08 -0400)
committerPeter Amstutz <peter.amstutz@curoverse.com>
Mon, 13 Apr 2015 21:08:42 +0000 (17:08 -0400)
services/fuse/arvados_fuse/__init__.py
services/fuse/bin/arv-mount
services/fuse/tests/test_mount.py

index deb0cd35a321a847d484437ffbbb31b85756a2d2..5bb21c60ea69124eb721dcfc1b8b9ed3b05dcf9a 100644 (file)
@@ -24,7 +24,7 @@ import ciso8601
 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')
 
@@ -56,7 +56,7 @@ class DirectoryHandle(object):
         self.dirobj.dec_use()
 
 
-class ObjectCache(object):
+class InodeCache(object):
     def __init__(self, cap):
         self._entries = collections.OrderedDict()
         self._counter = itertools.count(1)
@@ -69,11 +69,13 @@ class ObjectCache(object):
             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):
@@ -84,6 +86,7 @@ class ObjectCache(object):
     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]
 
 
@@ -91,10 +94,10 @@ class Inodes(object):
     """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]
@@ -112,6 +115,7 @@ class Inodes(object):
         return k in self._entries
 
     def touch(self, entry):
+        entry._atime = time.time()
         self._obj_cache.touch(entry)
 
     def cap_cache(self):
@@ -141,10 +145,10 @@ class Operations(llfuse.Operations):
 
     """
 
-    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
@@ -236,6 +240,7 @@ class Operations(llfuse.Operations):
         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):
@@ -245,8 +250,7 @@ class Operations(llfuse.Operations):
         else:
             raise llfuse.FUSEError(errno.EBADF)
 
-        # update atime
-        handle.fileobj._atime = time.time()
+        self.inodes.touch(handle.fileobj)
 
         try:
             with llfuse.lock_released:
@@ -286,14 +290,10 @@ class Operations(llfuse.Operations):
             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):
index b540efe82c63b59640e5c6c4d10a44e6de004606..9c0ef10e21128a23bcdafd9d9de51b5e49b5198b 100755 (executable)
@@ -45,6 +45,9 @@ with "--".
     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""")
@@ -81,7 +84,7 @@ with "--".
 
     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)
@@ -112,7 +115,7 @@ with "--".
         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))
index 4802d69c313f1a1053ef2b3015e984e856d77a60..ecc08888dff6349352ab940908a9d936591d39df 100644 (file)
@@ -25,7 +25,7 @@ class MountTestBase(unittest.TestCase):
         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, [])