- # The llfuse documentation recommends only overloading functions that
- # are actually implemented, as the default implementation will raise ENOSYS.
- # However, there is a bug in the llfuse default implementation of create()
- # "create() takes exactly 5 positional arguments (6 given)" which will crash
- # arv-mount.
- # The workaround is to implement it with the proper number of parameters,
- # and then everything works out.
- def create(self, inode_parent, name, mode, flags, ctx):
- raise llfuse.FUSEError(errno.EROFS)
+ def _check_writable(self, inode_parent):
+ if not self.enable_write:
+ raise llfuse.FUSEError(errno.EROFS)
+
+ if inode_parent in self.inodes:
+ p = self.inodes[inode_parent]
+ else:
+ raise llfuse.FUSEError(errno.ENOENT)
+
+ if not isinstance(p, Directory):
+ raise llfuse.FUSEError(errno.ENOTDIR)
+
+ if not p.writable():
+ raise llfuse.FUSEError(errno.EPERM)
+
+ return p
+
+ @catch_exceptions
+ def create(self, inode_parent, name, mode, flags, ctx=None):
+ _logger.debug("arv-mount create: parent_inode %i '%s' %o", inode_parent, name, mode)
+
+ p = self._check_writable(inode_parent)
+ p.create(name)
+
+ # The file entry should have been implicitly created by callback.
+ f = p[name]
+ fh = next(self._filehandles_counter)
+ self._filehandles[fh] = FileHandle(fh, f)
+ self.inodes.touch(p)
+
+ f.inc_ref()
+ return (fh, self.getattr(f.inode))
+
+ @catch_exceptions
+ def mkdir(self, inode_parent, name, mode, ctx=None):
+ _logger.debug("arv-mount mkdir: parent_inode %i '%s' %o", inode_parent, name, mode)
+
+ p = self._check_writable(inode_parent)
+ p.mkdir(name)
+
+ # The dir entry should have been implicitly created by callback.
+ d = p[name]
+
+ d.inc_ref()
+ return self.getattr(d.inode)
+
+ @catch_exceptions
+ def unlink(self, inode_parent, name, ctx=None):
+ _logger.debug("arv-mount unlink: parent_inode %i '%s'", inode_parent, name)
+ p = self._check_writable(inode_parent)
+ p.unlink(name)
+
+ @catch_exceptions
+ def rmdir(self, inode_parent, name, ctx=None):
+ _logger.debug("arv-mount rmdir: parent_inode %i '%s'", inode_parent, name)
+ p = self._check_writable(inode_parent)
+ p.rmdir(name)
+
+ @catch_exceptions
+ def rename(self, inode_parent_old, name_old, inode_parent_new, name_new, ctx=None):
+ _logger.debug("arv-mount rename: old_parent_inode %i '%s' new_parent_inode %i '%s'", inode_parent_old, name_old, inode_parent_new, name_new)
+ src = self._check_writable(inode_parent_old)
+ dest = self._check_writable(inode_parent_new)
+ dest.rename(name_old, name_new, src)
+
+ @catch_exceptions
+ def flush(self, fh):
+ if fh in self._filehandles:
+ self._filehandles[fh].flush()
+
+ def fsync(self, fh, datasync):
+ self.flush(fh)
+
+ def fsyncdir(self, fh, datasync):
+ self.flush(fh)