def relabel(self, new_name): fn = FileName(new_name, is_intl=self.is_intl) if not fn.is_valid(): raise FSError(INVALID_VOLUME_NAME, file_name=name, node=self) self.root.name = new_name self.root.write() self.name = new_name self.root_dir.name = new_name
def _create_node(self, node, name, meta_info, update_ts=True): self.ensure_entries() # make sure a default meta_info is available if meta_info == None: meta_info = MetaInfo() meta_info.set_current_as_mod_time() meta_info.set_default_protect() # check file name fn = FileName(name, is_intl=self.volume.is_intl) if not fn.is_valid(): raise FSError(INVALID_FILE_NAME, file_name=name, node=self) # does already exist an entry in this dir with this name? if self.has_name(fn): raise FSError(NAME_ALREADY_EXISTS, file_name=name, node=self) # calc hash index of name fn_hash = fn.hash() hash_chain = self.name_hash[fn_hash] if len(hash_chain) == 0: hash_chain_blk = 0 else: hash_chain_blk = hash_chain[0].block.blk_num # return the number of blocks required to create this node num_blks = node.blocks_get_create_num() # try to find free blocks free_blks = self.volume.bitmap.alloc_n(num_blks) if free_blks == None: raise FSError(NO_FREE_BLOCKS, node=self, file_name=name, extra="want %d" % num_blks) # now create the blocks for this node new_blk = node.blocks_create_new(free_blks, name, hash_chain_blk, self.block.blk_num, meta_info) # dircache: create record for this node if self.volume.is_dircache: ok = self._dircache_add_entry(name, meta_info, new_blk, node.get_size(), update_myself=False) if not ok: self.delete() raise FSError(NO_FREE_BLOCKS, node=self, file_name=name, extra="want dcache") # update my dir self.block.hash_table[fn_hash] = new_blk self.block.write() # add node self.name_hash[fn_hash].insert(0,node) self.entries.append(node) # update time stamps if update_ts: self.update_dir_mod_time() self.volume.update_disk_time()
def create(self, name, meta_info=None, dos_type=None, boot_code=None, is_ffs=False, is_intl=False, is_dircache=False): # determine dos_type if dos_type == None: dos_type = DosType.DOS0 if is_ffs: dos_type |= DosType.DOS_MASK_FFS if is_dircache: dos_type |= DosType.DOS_MASK_DIRCACHE elif is_intl: dos_type |= DosType.DOS_MASK_INTL # update flags self.is_ffs = DosType.is_ffs(dos_type) self.is_intl = DosType.is_intl(dos_type) self.is_dircache = DosType.is_dircache(dos_type) # convert and check volume name if not isinstance(name, FSString): raise ValueError("create's name must be a FSString") fn = FileName(name, is_intl=self.is_intl) if not fn.is_valid(): raise FSError(INVALID_VOLUME_NAME, file_name=name, node=self) # create a boot block self.boot = BootBlock(self.blkdev) self.boot.create(dos_type=dos_type, boot_code=boot_code) self.boot.write() # create a root block self.root = RootBlock(self.blkdev, self.boot.calc_root_blk) if meta_info == None: meta_info = RootMetaInfo() meta_info.set_current_as_create_time() meta_info.set_current_as_mod_time() meta_info.set_current_as_disk_time() create_ts = meta_info.get_create_ts() disk_ts = meta_info.get_disk_ts() mod_ts = meta_info.get_mod_ts() self.meta_info = meta_info self.root.create(name.get_ami_str(), create_ts, disk_ts, mod_ts) self.name = name # create bitmap self.bitmap = ADFSBitmap(self.root) self.bitmap.create() self.bitmap.write() # writes root block, too # create empty root dir self.root_dir = ADFSVolDir(self, self.root) self.root_dir.read() # all ok self.valid = True
def create(self, name, meta_info=None, dos_type=None, boot_code=None, is_ffs=False, is_intl=False, is_dircache=False, is_longname=False): # determine dos_type if dos_type == None: dos_type = DosType.DOS0 if is_longname: dos_type = DosType.DOS6 elif is_dircache: dos_type |= DosType.DOS_MASK_DIRCACHE elif is_intl: dos_type |= DosType.DOS_MASK_INTL if is_ffs: dos_type |= DosType.DOS_MASK_FFS # update flags self.is_ffs = DosType.is_ffs(dos_type) self.is_intl = DosType.is_intl(dos_type) self.is_dircache = DosType.is_dircache(dos_type) self.is_longname = DosType.is_longname(dos_type) # convert and check volume name if not isinstance(name, FSString): raise ValueError("create's name must be a FSString") fn = FileName(name, is_intl=self.is_intl, is_longname=False) # Volumes don't support long names if not fn.is_valid(): raise FSError(INVALID_VOLUME_NAME, file_name=name, node=self) # create a boot block self.boot = BootBlock(self.blkdev) self.boot.create(dos_type=dos_type, boot_code=boot_code) self.boot.write() # create a root block self.root = RootBlock(self.blkdev, self.boot.calc_root_blk) if meta_info == None: meta_info = RootMetaInfo() meta_info.set_current_as_create_time() meta_info.set_current_as_mod_time() meta_info.set_current_as_disk_time() create_ts = meta_info.get_create_ts() disk_ts = meta_info.get_disk_ts() mod_ts = meta_info.get_mod_ts() self.meta_info = meta_info self.root.create(name.get_ami_str(), create_ts, disk_ts, mod_ts, fstype=dos_type) self.name = name # create bitmap self.bitmap = ADFSBitmap(self.root) self.bitmap.create() self.bitmap.write() # writes root block, too # create empty root dir self.root_dir = ADFSVolDir(self, self.root) self.root_dir.read() # all ok self.valid = True
def relabel(self, name): """Relabel the volume""" # make sure its a FSString if not isinstance(name, FSString): raise ValueError("relabel's name must be a FSString") # validate file name fn = FileName(name, is_intl=self.is_intl) if not fn.is_valid(): raise FSError(INVALID_VOLUME_NAME, file_name=name, node=self) # update root block ami_name = name.get_ami_str() self.root.name = ami_name self.root.write() # store internally self.name = name self.root_dir.name = name
def get_path_name(self, path_name, allow_file=True, allow_dir=True): """get node for given path""" # make sure path name is a FSString if not isinstance(path_name, FSString): raise ValueError("get_path_name's path must be a FSString") # create and check file name fn = FileName(path_name, is_intl=self.is_intl) if not fn.is_valid(): raise FSError(INVALID_FILE_NAME, file_name=path_name, node=self) # find node if fn.is_root_path_alias(): # its the root node return self.root_dir else: # find a sub node path = fn.split_path() return self.root_dir.get_path(path, allow_file, allow_dir)
def _create_node(self, node, name, meta_info): self.ensure_entries() # make sure a default meta_info is available if meta_info == None: meta_info = MetaInfo() meta_info.set_current_time() meta_info.set_default_protect() # check file name fn = FileName(name) if not fn.is_valid(): raise FSError(INVALID_FILE_NAME, file_name=name, node=self) # does already exist an entry in this dir with this name? if self.has_name(fn): raise FSError(NAME_ALREADY_EXISTS, file_name=name, node=self) # calc hash index of name fn_hash = fn.hash() hash_chain = self.name_hash[fn_hash] if len(hash_chain) == 0: hash_chain_blk = 0 else: hash_chain_blk = hash_chain[0].block.blk_num # return the number of blocks required to create this node num_blks = node.blocks_get_create_num() # try to find free blocks free_blks = self.volume.bitmap.find_n_free(num_blks) if free_blks == None: raise FSError(NO_FREE_BLOCKS, node=self, file_name=name, extra="want %d" % num_blks) # update bitmap for b in free_blks: self.volume.bitmap.clr_bit(b) self.volume.bitmap.write_only_bits() # now create the blocks for this node new_blk = node.blocks_create_new(free_blks, name, hash_chain_blk, self.block.blk_num, meta_info) # update my dir self.block.hash_table[fn_hash] = new_blk self.block.write() # add node self.name_hash[fn_hash].insert(0,node) self.entries.append(node)
def create_dir(self, ami_path): """Create a new directory""" # make sure its a FSString if not isinstance(ami_path, FSString): raise ValueError("create_dir's ami_path must be a FSString") # check file path fn = FileName(ami_path, is_intl=self.is_intl) if not fn.is_valid(): raise FSError(INVALID_FILE_NAME, file_name=ami_path) # split into dir and base name dir_name, base_name = fn.get_dir_and_base_name() if base_name == None: raise FSError(INVALID_FILE_NAME, file_name=ami_path) # find parent of dir if dir_name == None: node = self.root_dir else: # no parent dir found node = self.get_dir_path_name(dir_name) if node == None: raise FSError(INVALID_PARENT_DIRECTORY, file_name=ami_path, extra="not found: "+dir_name) node.create_dir(base_name)
def get_create_path_name(self, path_name, suggest_name=None): """get a parent node and path name for creation return: parent_node_or_none, file_name_or_none """ # make sure input is correct if not isinstance(path_name, FSString): raise ValueError( "get_create_path_name's path_name must be a FSString") if suggest_name != None and not isinstance(suggest_name, FSString): raise ValueError( "get_create_path_name's suggest_name must be a FSString") # is root path? fn = FileName(path_name, is_intl=self.is_intl) if not fn.is_valid(): raise FSError(INVALID_FILE_NAME, file_name=path_name, node=self) # find node if fn.is_root_path_alias(): return self.root_dir, suggest_name else: # try to get path_name as a directory node = self.get_dir_path_name(path_name) if node != None: return node, suggest_name else: # split into dir and file name dn, fn = fn.get_dir_and_base_name() if dn != None: # has a directory -> try to fetch it node = self.get_dir_path_name(dn) else: # no dir -> assume root dir node = self.root_dir if fn != None: # take given name return node, fn else: # use suggested name return node, suggest_name
def get_create_path_name(self, path_name, suggest_name=None): """get a parent node and path name for creation return: parent_node_or_none, file_name_or_none """ # make sure input is correct if not isinstance(path_name, FSString): raise ValueError("get_create_path_name's path_name must be a FSString") if suggest_name != None and not isinstance(suggest_name, FSString): raise ValueError("get_create_path_name's suggest_name must be a FSString") # is root path? fn = FileName(path_name, is_intl=self.is_intl) if not fn.is_valid(): raise FSError(INVALID_FILE_NAME, file_name=path_name, node=self) # find node if fn.is_root_path_alias(): return self.root_dir, suggest_name else: # try to get path_name as a directory node = self.get_dir_path_name(path_name) if node != None: return node, suggest_name else: # split into dir and file name dn, fn = fn.get_dir_and_base_name() if dn != None: # has a directory -> try to fetch it node = self.get_dir_path_name(dn) else: # no dir -> assume root dir node = self.root_dir if fn != None: # take given name return node, fn else: # use suggested name return node, suggest_name
def create_dir(self, ami_path): """Create a new directory""" # make sure its a FSString if not isinstance(ami_path, FSString): raise ValueError("create_dir's ami_path must be a FSString") # check file path fn = FileName(ami_path, is_intl=self.is_intl) if not fn.is_valid(): raise FSError(INVALID_FILE_NAME, file_name=ami_path) # split into dir and base name dir_name, base_name = fn.get_dir_and_base_name() if base_name == None: raise FSError(INVALID_FILE_NAME, file_name=ami_path) # find parent of dir if dir_name == None: node = self.root_dir else: # no parent dir found node = self.get_dir_path_name(dir_name) if node == None: raise FSError(INVALID_PARENT_DIRECTORY, file_name=ami_path, extra="not found: " + dir_name) node.create_dir(base_name)