def close_block(self, block_id): """Close a block """ if block_id not in self.open_messages: return debug_print("Closing open block %d" % block_id) self.open_messages[block_id].close() self.open_messages.pop(block_id)
def close_blocks(self): """Closes all open blocks """ # Close all blocks for block_id, block in self.open_messages.items(): debug_print("Closing open block %d" % block_id) block.close() self.open_messages = {}
def releasedir(self, path): node = self.get_node_by_path(path) if not node: return -fuse.ENOENT debug_print("Closing %s/" % path) node.flush()
def release(self, path, flags): node = self.get_node_by_path(path) if not node: return -fuse.ENOENT debug_print("Closing %s" % path) node.close_blocks() node.flush()
def truncate(self, path, size): node = self.get_node_by_path(path) if not node: return -fuse.ENOENT if node.__class__ != file.File: return -fuse.EISDIR debug_print("Resizing %s to %d" % (path, size)) node.truncate(size)
def readdir(self, path, offset): node = self.get_node_by_path(path) if node.__class__ != directory.Directory: return debug_print("Listing %s/" % path) yield fuse.Direntry(".") yield fuse.Direntry("..") for child_name in node.children.values(): yield fuse.Direntry(child_name)
def mkdir(self, path, mode): parent = self.get_node_by_path(self.get_path_parent(path)) if not parent: return -fuse.ENOENT if parent.get_child_by_name(self.get_path_filename(path)): return -fuse.EEXIST debug_print("Creating directory %s/" % path) child = directory.Directory.create(self.imap) self.open_nodes[child.message.name] = child parent.add_child(child.message.name, self.get_path_filename(path))
def read(self, path, size, offset): node = self.get_node_by_path(path) if not node: return -fuse.ENOENT if node.__class__ != file.File: return -fuse.EISDIR node.seek(offset) data = str(node.read(size)) debug_print("Read %d-%d returned %d bytes" % (offset, size + offset, len(data))) return data
def mknod(self, path, mode, dev): parent = self.get_node_by_path(self.get_path_parent(path)) if not parent: return -fuse.ENOENT if parent.get_child_by_name(self.get_path_filename(path)): return -fuse.EEXIST debug_print("Creating file %s" % path) node = file.File.create(self.imap) self.open_nodes[node.message.name] = node parent.add_child(node.message.name, self.get_path_filename(path))
def unlink(self, path): node = self.get_node_by_path(path) if not node or node.__class__ != file.File: return -fuse.ENOENT parent = self.get_node_by_path(self.get_path_parent(path)) if not parent: return -fuse.ENOENT debug_print("Removing %s" % path) parent.remove_child(node.message.name) node.delete() self.open_nodes.pop(node.message.name)
def write(self, path, buf, offset): node = self.get_node_by_path(path) if not node: return -fuse.ENOENT if node.__class__ != file.File: return -fuse.EISDIR byte_buf = bytearray(buf) node.seek(offset) node.write(byte_buf) debug_print("Write %d-%d" % (offset, offset + len(buf))) return len(buf)
def open_block(self, block_id): """Open a block """ if block_id in self.open_messages: return self.open_messages[block_id] else: debug_print("Opening block %d" % block_id) if block_id not in self.blocks: # Create first block = self.create_block(block_id) return block else: block_key = self.blocks[block_id] msg = message.Message.open(self.message.conn, block_key, compressed=True) self.open_messages[block_id] = msg return msg
def rename(self, oldpath, newpath): # handle dir name if not self.get_path_filename(newpath): newpath += self.get_path_filename(oldpath) debug_print("Moving %s to %s" % (oldpath, newpath)) # handle same-parent if self.get_path_parent(oldpath) == self.get_path_parent(newpath): parent = self.get_node_by_path(self.get_path_parent(oldpath)) if not parent: return -fuse.ENOENT # For simplicity we do not allow overwriting new_child_key = parent.get_child_by_name( self.get_path_filename(newpath)) if new_child_key: return -fuse.EEXIST child_key = parent.get_child_by_name( self.get_path_filename(oldpath)) parent.children[child_key] = self.get_path_filename(newpath) parent.dirty = True else: # Different parent old_node = self.get_node_by_path(oldpath) if not old_node: return -fuse.ENOENT old_parent = self.get_node_by_path(self.get_path_parent(oldpath)) if not old_parent: return -fuse.ENOENT # For simplicity we do not allow overwriting new_node = self.get_node_by_path(newpath) if new_node: return -fuse.EEXIST new_parent = self.get_node_by_path(self.get_path_parent(newpath)) # Remove old, add new new_parent.add_child(old_node.message.name, self.get_path_filename(oldpath)) old_parent.remove_child(old_node.message.name)
def rmdir(self, path): child = self.get_node_by_path(path) if not child: return -fuse.ENOENT if child.__class__ != directory.Directory: return -fuse.ENOTDIR if len(child.children) > 0: return -fuse.ENOTEMPTY parent = self.get_node_by_path(self.get_path_parent(path)) if not parent: return -fuse.ENOENT debug_print("Removing directory %s/" % path) parent.remove_child(child.message.name) self.close_node(child) message.Message.unlink(self.imap, child.message.name)
def rename(self, oldpath, newpath): # handle dir name if not self.get_path_filename(newpath): newpath += self.get_path_filename(oldpath) debug_print("Moving %s to %s" % (oldpath, newpath)) # handle same-parent if self.get_path_parent(oldpath) == self.get_path_parent(newpath): parent = self.get_node_by_path(self.get_path_parent(oldpath)) if not parent: return -fuse.ENOENT # For simplicity we do not allow overwriting new_child_key = parent.get_child_by_name(self.get_path_filename(newpath)) if new_child_key: return -fuse.EEXIST child_key = parent.get_child_by_name(self.get_path_filename(oldpath)) parent.children[child_key] = self.get_path_filename(newpath) parent.dirty = True else: # Different parent old_node = self.get_node_by_path(oldpath) if not old_node: return -fuse.ENOENT old_parent = self.get_node_by_path(self.get_path_parent(oldpath)) if not old_parent: return -fuse.ENOENT # For simplicity we do not allow overwriting new_node = self.get_node_by_path(newpath) if new_node: return -fuse.EEXIST new_parent = self.get_node_by_path(self.get_path_parent(newpath)) # Remove old, add new new_parent.add_child(old_node.message.name, self.get_path_filename(oldpath)) old_parent.remove_child(old_node.message.name)
def flush(self): """Write any changes to the server """ if self.dirty: debug_print("Flushing %d bytes" % len(self.data)) # Find old uid old_uid = self.conn.get_uid_by_subject(self.name) # Store message # Compress, if requested if self.compress: data_str = self.conn.enc.compress(str(self.data)) else: data_str = str(self.data) self.conn.put_message(self.name, data_str) # Delete old version if old_uid: self.conn.delete_message(old_uid) self.dirty = False