def load_gdtable(group_number): group_bn = fs.gpn_to_bn( group_number, fs.bytes_to_int(superblock.get_field(superblock.s_blocks_per_group)) ) for bn, gdtable_block in enumerate(gdtable_blocks): gdtable_block.offset_bn = group_bn + 1 gdtable_block.load(bn + group_bn + 1)
def free_file_blocks(inode_block, inode, i_block): blocks_per_group = fs.bytes_to_int(superblock.get_field(superblock.s_blocks_per_group)) inode_tn = get_table_number(inode) gpn = get_group_number(inode) blocks_count = fs.bytes_to_int(inode_block.get_field( inode_tn, inode_block.i_blocks )) if blocks_count > 0: bg_block = gdtable.get_gdtableblock(gpn) blockbitmap.block_bitmap.load(fs.bytes_to_int(bg_block.get_field(gpn, bg_block.bg_block_bitmap))) first_blocks = [fs.bytes_to_int(i_block[i: i + fs.ADDRESS_SIZE]) for i in range(0, blocks_count * fs.ADDRESS_SIZE, fs.ADDRESS_SIZE)] for bn in first_blocks: blockbitmap.set_free_block(fs.bn_to_igbn(bn, blocks_per_group)) blockbitmap.block_bitmap.unload(fs.bytes_to_int(bg_block.get_field(gpn, bg_block.bg_block_bitmap)))
def find_first_free_record_in_block(file_size=None, offset=0): rlength = None length = file_size % data_block_buffer.block_size if file_size else data_block_buffer.block_size while offset < length: inode = fs.bytes_to_int( data_block_buffer.get_bytes(offset, IN_FIELD_SIZE)) rlength = fs.bytes_to_int( data_block_buffer.get_bytes(offset + IN_FIELD_SIZE, RL_FIELD_SIZE)) if inode == 0: return rlength, offset offset += rlength if rlength is not None: return None, offset - rlength else: return None, 0
def find_record_in_block(filename, file_size=None): offset = 0 length = file_size % data_block_buffer.block_size if file_size else data_block_buffer.block_size while offset < length: rlength = fs.bytes_to_int( data_block_buffer.get_bytes(offset + IN_FIELD_SIZE, RL_FIELD_SIZE)) nlength = fs.bytes_to_int( data_block_buffer.get_bytes(offset + IN_FIELD_SIZE + RL_FIELD_SIZE, NL_FIELD_SIZE)) rname = data_block_buffer.get_bytes( offset + IN_FIELD_SIZE + RL_FIELD_SIZE + NL_FIELD_SIZE, nlength) inode = fs.bytes_to_int( data_block_buffer.get_bytes(offset, IN_FIELD_SIZE)) if filename == rname.decode(encoding='ASCII') and inode != 0: return offset else: offset += rlength
def unload_inode(number): block_size = fs.bytes_to_int(superblock.get_field(superblock.s_log_block_size)) * 1024 for i, block in enumerate(inodetable_blocks_list): if block.first_inode_number <= number < block.first_inode_number + block_size // fs.INODE_SIZE: block.unload(block.block_buffer_bn) if block.loads_count <= 1: del inodetable_blocks_list[i] else: block.loads_count -= 1 break
def chmod(path, mode): fd = openfile.create_file_descriptor(path, openfile.O_RDONLY, 0) ino = fdtable.get_inode(fd) inode_tn = inodetable.get_table_number(ino) inode_block = inodetable.load_inode(ino) i_mode = fs.bytes_to_int(inode_block.get_field(inode_tn, inode_block.i_mode)) i_uid = fs.bytes_to_int(inode_block.get_field(inode_tn, inode_block.i_uid)) try: if user.get_uid() != i_uid and user.get_uid() != 0: raise permissions.PermissionsError(i_mode) if i_mode & inodetable.S_IFREG == inodetable.S_IFREG: inode_block.set_field(inode_tn, inode_block.i_mode, inodetable.S_IFREG | int(mode)) else: inode_block.set_field(inode_tn, inode_block.i_mode, inodetable.S_IFDIR | int(mode)) finally: inodetable.unload_inode(ino) closefile.close_file(fd) return 0
def extend_file_blocks(inode_block, inode, i_block): inode_tn = get_table_number(inode) gpn = get_group_number(inode) bg_block = gdtable.get_gdtableblock(gpn) blockbitmap.block_bitmap.load(fs.bytes_to_int(bg_block.get_field(gpn, bg_block.bg_block_bitmap))) igbn = blockbitmap.find_first_free_block() blocks_count = fs.bytes_to_int(inode_block.get_field( inode_tn, inode_block.i_blocks )) i_block[blocks_count * fs.ADDRESS_SIZE: (blocks_count+1) * fs.ADDRESS_SIZE] = fs.int_to_bytes( igbn + gpn * fs.bytes_to_int(superblock.get_field(superblock.s_blocks_per_group)), fs.ADDRESS_SIZE ) inode_block.set_field(inode_tn, inode_block.i_block, i_block) inode_block.set_field(inode_tn, inode_block.i_blocks, blocks_count + 1) blockbitmap.set_used_block(igbn) blockbitmap.block_bitmap.unload(fs.bytes_to_int(bg_block.get_field(gpn, bg_block.bg_block_bitmap))) return igbn + gpn * fs.bytes_to_int(superblock.get_field(superblock.s_blocks_per_group))
def load_inode(number): block_size = fs.bytes_to_int(superblock.get_field(superblock.s_log_block_size)) * 1024 for block in inodetable_blocks_list: if block.first_inode_number <= number <= block.first_inode_number + block_size // fs.INODE_SIZE: block.loads_count += 1 return block gn = number // fs.bytes_to_int(superblock.get_field(superblock.s_inodes_per_group)) table_number = get_table_number(number) gdtable_block = gdtable.get_gdtableblock(gn) inode_table_bn = fs.bytes_to_int(gdtable_block.get_field(gn, gdtable_block.bg_inode_table)) inode_bn = inode_table_bn + table_number * fs.INODE_SIZE // block_size inode_table_block = systableblock.SysTableBlock(fs.INODE_TYPE, inode_table_bn) inode_table_block.init_struct(fs.INODE_NAME) inode_table_block.load(inode_bn) inode_table_block.first_inode_number = (inode_bn - inode_table_bn) * block_size // fs.INODE_SIZE \ + gn * fs.bytes_to_int(superblock.get_field(superblock.s_inodes_per_group)) inode_table_block.loads_count = 1 inodetable_blocks_list.append(inode_table_block) return inode_table_block
def load_superblock(partition_name): device.init_device(512) device.vdevice.bound_partition(partition_name) # block size loading hack balloc.init_balloc(512) # 512b - minimum block size (sector's size) superblock.load(0) balloc.init_balloc( fs.bytes_to_int(superblock.get_field(superblock.s_log_block_size)) * 1024) superblock.load(0)
def create_block_bitmap(group_number): def fillbitmap(first_data_bn, blocks_per_group): remaining_blocks_count = first_data_bn % 8 for b in range(first_data_bn // 8): yield 255 if remaining_blocks_count != 0: yield 255 >> (8 - remaining_blocks_count) free_blocks = (blocks_per_group - first_data_bn) // 8 for b in range(free_blocks): yield 0 gbn = fs.gpn_to_bn( group_number, fs.bytes_to_int(superblock.get_field(superblock.s_blocks_per_group))) bitmap_bytes_count = math.ceil( fs.bytes_to_int(superblock.get_field(superblock.s_blocks_per_group)) / 8) gdtable_block = gdtable.get_gdtableblock(group_number) bitmap_bn = fs.bytes_to_int( gdtable_block.get_field(group_number, gdtable_block.bg_block_bitmap)) blockbitmap.block_bitmap.load(bitmap_bn) blockbitmap.block_bitmap.block_buffer[:bitmap_bytes_count] = bytes( fillbitmap( fs.bytes_to_int(superblock.get_field( superblock.s_first_data_block)) + 1 if group_number == 0 else fs.bytes_to_int( superblock.get_field(superblock.s_first_data_block)), fs.bytes_to_int(superblock.get_field( superblock.s_blocks_per_group)))) blockbitmap.block_bitmap.unload(bitmap_bn)
def write_to_end(fd, buf, nbytes): inode = fdtable.get_inode(fd) inode_tn = inodetable.get_table_number(inode) file_inodetable_block = inodetable.load_inode(inode) i_block = file_inodetable_block.get_field(inode_tn, file_inodetable_block.i_block) file_size = fs.bytes_to_int( file_inodetable_block.get_field(inode_tn, file_inodetable_block.i_size)) block_size = fs.bytes_to_int( superblock.get_field(superblock.s_log_block_size)) * 1024 last_block_size = file_size % block_size if last_block_size == 0: last_bn = inodetable.extend_file_blocks(file_inodetable_block, inode, i_block) else: last_bn = inodetable.get_last_file_bn(i_block) data_block_buffer.load(last_bn) if last_block_size + nbytes > block_size: last_bn = inodetable.extend_file_blocks(file_inodetable_block, inode, i_block) remaining_bytes_count = block_size - last_block_size data_block_buffer.set_bytes(last_block_size, buf[:remaining_bytes_count]) data_block_buffer.unload(data_block_buffer.block_number) data_block_buffer.load(last_bn) data_block_buffer.set_bytes(0, buf[remaining_bytes_count:nbytes]) else: data_block_buffer.set_bytes(last_block_size, buf[:nbytes]) file_inodetable_block.set_field(inode_tn, file_inodetable_block.i_size, file_size + nbytes) data_block_buffer.unload(last_bn) file_inodetable_block.set_field(inode_tn, file_inodetable_block.i_mtime, int(time.time())) inodetable.unload_inode(inode)
def read_by_offset(fd, nbytes): inode = fdtable.get_inode(fd) offset = fdtable.get_offset(fd) inode_tn = inodetable.get_table_number(inode) file_inodetable_block = inodetable.load_inode(inode) i_block = file_inodetable_block.get_field(inode_tn, file_inodetable_block.i_block) file_size = fs.bytes_to_int( file_inodetable_block.get_field(inode_tn, file_inodetable_block.i_size)) block_size = fs.bytes_to_int( superblock.get_field(superblock.s_log_block_size)) * 1024 if offset >= file_size: raise OffsetError(offset) lbn = offset // block_size b_offset = offset % block_size buf = bytearray() if b_offset + nbytes > block_size: first_bytes_count = block_size - b_offset data_block_buffer.load(inodetable.lbn_to_bn(lbn, i_block)) buf[:first_bytes_count] = data_block_buffer.get_bytes( b_offset, first_bytes_count) data_block_buffer.load(inodetable.lbn_to_bn(lbn + 1, i_block)) buf[first_bytes_count:nbytes] = data_block_buffer.get_bytes( 0, nbytes - first_bytes_count) else: data_block_buffer.load(inodetable.lbn_to_bn(lbn, i_block)) buf[:] = data_block_buffer.get_bytes(b_offset, nbytes) fdtable.set_offset(fd, offset + nbytes) file_inodetable_block.set_field(inode_tn, file_inodetable_block.i_atime, int(time.time())) inodetable.unload_inode(inode) return bytes(buf)
def find_file_record(inode_block, inode_table_number, filename): file_size = fs.bytes_to_int( inode_block.get_field(inode_table_number, inode_block.i_size)) if file_size == 0: return blocks_count = fs.bytes_to_int( inode_block.get_field(inode_table_number, inode_block.i_blocks)) i_block = inode_block.get_field(inode_table_number, inode_block.i_block) offset = 0 for lbn in range(blocks_count): bn = inodetable.lbn_to_bn(lbn, i_block) data_block_buffer.load(bn) if lbn == blocks_count - 1: offset = find_record_in_block(filename, file_size) else: offset = find_record_in_block(filename) if offset: break return offset
def stat(path): fd = openfile.create_file_descriptor(path, openfile.O_STAT, 0) ino = fdtable.get_inode(fd) inode_tn = inodetable.get_table_number(ino) inode_block = inodetable.load_inode(ino) mode = fs.bytes_to_int(inode_block.get_field(inode_tn, inode_block.i_mode)) uid = fs.bytes_to_int(inode_block.get_field(inode_tn, inode_block.i_uid)) gid = fs.bytes_to_int(inode_block.get_field(inode_tn, inode_block.i_gid)) size = fs.bytes_to_int(inode_block.get_field(inode_tn, inode_block.i_size)) atime = fs.bytes_to_int( inode_block.get_field(inode_tn, inode_block.i_atime)) mtime = fs.bytes_to_int( inode_block.get_field(inode_tn, inode_block.i_mtime)) ctime = fs.bytes_to_int( inode_block.get_field(inode_tn, inode_block.i_ctime)) blocks = fs.bytes_to_int( inode_block.get_field(inode_tn, inode_block.i_blocks)) inodetable.unload_inode(ino) closefile.close_file(fd) return ino, mode, uid, gid, size, atime, mtime, ctime, blocks
def check_gid(inode_block, inode_n, gid): inode_tn = get_table_number(inode_n) i_gid = fs.bytes_to_int(inode_block.get_field(inode_tn, inode_block.i_gid)) return i_gid == gid
def create_file_descriptor(path, oflag, mode): names = [n for n in path.split('/') if n != ''] dir_table_in = 0 dir_inodetable_block = inodetable.load_inode(dir_table_in) dir_in = 0 perm = inodetable.S_IRUSR | inodetable.S_IRGRP | inodetable.S_IROTH if not permissions.check_file_permissions(dir_inodetable_block, dir_in, perm): raise permissions.PermissionsError(perm) if path != '/': if len(names) > 1: for n in names[:-1]: offset = filerecord.find_file_record(dir_inodetable_block, dir_table_in, n) inodetable.unload_inode(dir_in) if offset is None: raise createfile.DirNotFoundError(n) dir_in = filerecord.get_record_inode_number(offset) dir_table_in = inodetable.get_table_number(dir_in) dir_inodetable_block = inodetable.load_inode(dir_in) if not permissions.check_file_permissions( dir_inodetable_block, dir_in, perm): raise permissions.PermissionsError(perm) if fs.bytes_to_int( dir_inodetable_block.get_field( dir_table_in, dir_inodetable_block.i_mode) ) & inodetable.S_IFDIR != inodetable.S_IFDIR: raise createfile.DirNotFoundError(n) offset = filerecord.find_file_record(dir_inodetable_block, dir_table_in, names[-1]) if oflag == O_WRONLY: perm = inodetable.S_IWUSR | inodetable.S_IWGRP | inodetable.S_IWOTH if oflag == O_RDWR: perm |= inodetable.S_IWUSR | inodetable.S_IWGRP | inodetable.S_IWOTH if offset is None: raise deletefile.FileNotExistsError(names[-1]) inode_n = filerecord.get_record_inode_number(offset) inode_table_n = inodetable.get_table_number(inode_n) file_inodetable_block = inodetable.load_inode(inode_n) else: if oflag == O_WRONLY: perm = inodetable.S_IWUSR | inodetable.S_IWGRP | inodetable.S_IWOTH if oflag == O_RDWR: perm |= inodetable.S_IWUSR | inodetable.S_IWGRP | inodetable.S_IWOTH inode_n = dir_in inode_table_n = dir_table_in file_inodetable_block = dir_inodetable_block if fs.bytes_to_int( file_inodetable_block.get_field( inode_table_n, file_inodetable_block.i_mode)) & mode != mode: raise deletefile.WrongFileTypeError(names[-1]) if oflag != O_STAT: if not permissions.check_file_permissions(file_inodetable_block, inode_n, perm): raise permissions.PermissionsError(perm) inodetable.unload_inode(dir_in) inodetable.unload_inode(0) return fdtable.reserve_fd(inode_n)
def get_record_inode_number(offset): return fs.bytes_to_int(data_block_buffer.get_bytes(offset, IN_FIELD_SIZE))
def get_gdtableblock(index): bn = index * fs.GD_SIZE // (fs.bytes_to_int(superblock.get_field(superblock.s_log_block_size)) * 1024) return gdtable_blocks[bn]
def create_file_record(inode_block, inode_table_number, file_inode_number, filename): file_size = fs.bytes_to_int( inode_block.get_field(inode_table_number, inode_block.i_size)) if file_size == 0: inode_block.set_field( inode_table_number, inode_block.i_size, IN_FIELD_SIZE + RL_FIELD_SIZE + NL_FIELD_SIZE + len(filename)) if fs.bytes_to_int( inode_block.get_field(inode_table_number, inode_block.i_blocks)) == 0: inode_block.set_field(inode_table_number, inode_block.i_blocks, 1) gn = inodetable.get_group_number(inode_block.first_inode_number) bg_block = gdtable.get_gdtableblock(gn) blockbitmap.block_bitmap.load( fs.bytes_to_int( bg_block.get_field(gn, bg_block.bg_block_bitmap))) free_bn = blockbitmap.find_first_free_block() blockbitmap.set_used_block(free_bn) inode_block.set_field( inode_table_number, inode_block.i_block, fs.int_to_bytes(free_bn, inode_block.i_block[sysblock.SIZE_INDEX])) blockbitmap.block_bitmap.unload( fs.bytes_to_int( bg_block.get_field(gn, bg_block.bg_block_bitmap))) inode_block.set_field(inode_table_number, inode_block.i_ctime, int(time.time())) bn = fs.bytes_to_int( inode_block.get_field(inode_table_number, inode_block.i_block)[:fs.ADDRESS_SIZE]) data_block_buffer.load(bn) create_file_record_in_block(0, file_inode_number, filename) inode_block.set_field(inode_table_number, inode_block.i_mtime, int(time.time())) data_block_buffer.unload(bn) return None blocks_count = fs.bytes_to_int( inode_block.get_field(inode_table_number, inode_block.i_blocks)) i_block = inode_block.get_field(inode_table_number, inode_block.i_block) bn, offset = 0, 0 filename_encoded = filename.encode(encoding='ASCII') for lbn in range(blocks_count): bn = inodetable.lbn_to_bn(lbn, i_block) data_block_buffer.load(bn) if lbn == blocks_count - 1: rlength, offset = find_first_free_record_in_block(file_size) while rlength and len( filename_encoded ) > rlength - IN_FIELD_SIZE - NL_FIELD_SIZE - RL_FIELD_SIZE: rlength, offset = find_first_free_record_in_block( file_size, offset + rlength) else: rlength, offset = find_first_free_record_in_block() while rlength and len( filename_encoded ) > rlength - IN_FIELD_SIZE - NL_FIELD_SIZE - RL_FIELD_SIZE: rlength, offset = find_first_free_record_in_block(offset + rlength) if offset: break if not rlength: extend_dir_file( inode_block, inode_table_number, IN_FIELD_SIZE + RL_FIELD_SIZE + NL_FIELD_SIZE + len(filename_encoded)) create_file_record_in_block(file_size, file_inode_number, filename) else: create_file_record_in_block(offset, file_inode_number, filename) inode_block.set_field(inode_table_number, inode_block.i_mtime, int(time.time())) data_block_buffer.unload(bn)
def create_file_record(path, mode): if path == '/': raise FileAlreadyExistsError('/') names = [n for n in path.split('/') if n != ''] bg_block = gdtable.get_gdtableblock(0) inodebitmap.inode_bitmap.load( fs.bytes_to_int(bg_block.get_field(0, bg_block.bg_inode_bitmap))) inode_ign = inodebitmap.find_first_free_inode() inode_n = fs.ign_to_in( 0, fs.bytes_to_int(superblock.get_field(superblock.s_inodes_per_group)), inode_ign) dir_table_in = 0 dir_inodetable_block = inodetable.load_inode(dir_table_in) dir_in = 0 perm = inodetable.S_IRUSR | inodetable.S_IRGRP | inodetable.S_IROTH if not permissions.check_file_permissions(dir_inodetable_block, dir_in, perm): raise permissions.PermissionsError(perm) if len(names) > 1: for n in names[:-1]: offset = filerecord.find_file_record(dir_inodetable_block, dir_table_in, n) inodetable.unload_inode(dir_in) if offset is None: raise DirNotFoundError(n) dir_in = filerecord.get_record_inode_number(offset) dir_table_in = inodetable.get_table_number(dir_in) dir_inodetable_block = inodetable.load_inode(dir_in) if not permissions.check_file_permissions(dir_inodetable_block, dir_in, perm): raise permissions.PermissionsError(perm) if fs.bytes_to_int( dir_inodetable_block.get_field(dir_table_in, dir_inodetable_block.i_mode) ) & inodetable.S_IFDIR != inodetable.S_IFDIR: raise DirNotFoundError(n) perm = inodetable.S_IWUSR | inodetable.S_IWGRP | inodetable.S_IWOTH if not permissions.check_file_permissions(dir_inodetable_block, dir_in, perm): raise permissions.PermissionsError(perm) offset = filerecord.find_file_record(dir_inodetable_block, dir_table_in, names[-1]) if offset is None: filerecord.create_file_record(dir_inodetable_block, dir_table_in, inode_n, names[-1]) dir_inodetable_block.set_field(dir_table_in, dir_inodetable_block.i_mtime, int(time.time())) else: raise FileAlreadyExistsError(names[-1]) inodetable_block = inodetable.load_inode(inode_n) inodetable_block.set_field(inode_ign, inodetable_block.i_mode, mode) inodetable_block.set_field(inode_ign, inodetable_block.i_uid, user.get_uid()) inodetable_block.set_field(inode_ign, inodetable_block.i_size, 0) inodetable_block.set_field(inode_ign, inodetable_block.i_atime, 0) inodetable_block.set_field(inode_ign, inodetable_block.i_mtime, 0) inodetable_block.set_field(inode_ign, inodetable_block.i_ctime, int(time.time())) inodetable_block.set_field(inode_ign, inodetable_block.i_dtime, 0) inodetable_block.set_field(inode_ign, inodetable_block.i_gid, user.get_gid()) inodetable_block.set_field(inode_ign, inodetable_block.i_blocks, 0) inodetable_block.set_field(inode_ign, inodetable_block.i_flags, 0) inodetable_block.set_field(inode_ign, inodetable_block.i_block, bytes(60)) inodetable_block.set_field( inode_ign, inodetable_block.i_pad, bytes(inodetable_block.i_pad[sysblock.SIZE_INDEX])) inodebitmap.set_used_inode(inode_ign) inodebitmap.inode_bitmap.unload( fs.bytes_to_int(bg_block.get_field(0, bg_block.bg_inode_bitmap))) inodetable.unload_inode(inode_n) inodetable.unload_inode(0) return fdtable.reserve_fd(inode_n)
def get_last_file_bn(i_block): first_blocks = [bn for bn in [fs.bytes_to_int(i_block[i: i + fs.ADDRESS_SIZE]) for i in range(0, (I_BLOCK_SIZE // fs.ADDRESS_SIZE - 3) * fs.ADDRESS_SIZE, fs.ADDRESS_SIZE)] if bn != 0] return first_blocks[-1]
def load(self, block_number): if self.block_size is None: self.block_size = fs.bytes_to_int( superblock.get_field(superblock.s_log_block_size)) * 1024 self.block_number = block_number self.block_buffer = bytearray(balloc.read_block(block_number))
def load_bg_table(self): gdtable.init_gdtable(fs.get_groups_count( fs.bytes_to_int(self.superblock.get_field(self.superblock.s_blocks_count)), fs.bytes_to_int(self.superblock.get_field(self.superblock.s_blocks_per_group)) )) gdtable.load_gdtable(0)
def check_file_permissions(inode_block, inode_n, perm): inode_tn = get_table_number(inode_n) i_mode = fs.bytes_to_int(inode_block.get_field(inode_tn, inode_block.i_mode)) return i_mode & perm == perm
def get_group_number(number): return number // fs.bytes_to_int(superblock.get_field(superblock.s_inodes_per_group))
def lbn_to_bn(lbn, i_block): first_blocks = [fs.bytes_to_int(i_block[i: i + fs.ADDRESS_SIZE]) for i in range(0, (I_BLOCK_SIZE // fs.ADDRESS_SIZE - 3) * fs.ADDRESS_SIZE, fs.ADDRESS_SIZE)] return first_blocks[lbn]
def delete_file_record(path, mode): if path == '/': raise WrongFileTypeError(path) names = [n for n in path.split('/') if n != ''] bg_block = gdtable.get_gdtableblock(0) inodebitmap.inode_bitmap.load( fs.bytes_to_int(bg_block.get_field(0, bg_block.bg_inode_bitmap))) dir_table_in = 0 dir_inodetable_block = inodetable.load_inode(dir_table_in) dir_in = 0 perm = inodetable.S_IRUSR | inodetable.S_IRGRP | inodetable.S_IROTH if not permissions.check_file_permissions(dir_inodetable_block, dir_in, perm): raise permissions.PermissionsError(perm) if len(names) > 1: for n in names[:-1]: offset = filerecord.find_file_record(dir_inodetable_block, dir_table_in, n) if dir_in != 0: inodetable.unload_inode(dir_in) if offset is None: raise createfile.DirNotFoundError(n) dir_in = filerecord.get_record_inode_number(offset) dir_table_in = inodetable.get_table_number(dir_in) dir_inodetable_block = inodetable.load_inode(dir_in) if not permissions.check_file_permissions(dir_inodetable_block, dir_in, perm): raise permissions.PermissionsError(perm) if fs.bytes_to_int( dir_inodetable_block.get_field(dir_table_in, dir_inodetable_block.i_mode) ) & inodetable.S_IFDIR != inodetable.S_IFDIR: raise createfile.DirNotFoundError(n) perm = inodetable.S_IWUSR | inodetable.S_IWGRP | inodetable.S_IWOTH if not permissions.check_file_permissions(dir_inodetable_block, dir_in, perm): raise permissions.PermissionsError(perm) offset = filerecord.find_file_record(dir_inodetable_block, dir_table_in, names[-1]) bn = data_block_buffer.block_number if offset is None: raise FileNotExistsError(names[-1]) inode_n = filerecord.get_record_inode_number(offset) inode_table_n = inodetable.get_table_number(inode_n) file_inodetable_block = inodetable.load_inode(inode_n) if fs.bytes_to_int( file_inodetable_block.get_field( inode_table_n, file_inodetable_block.i_mode)) & mode != mode: raise WrongFileTypeError(names[-1]) if mode & inodetable.S_IFDIR == inodetable.S_IFDIR: fd = opendir.opendir(path) try: readdir.readdir(fd) raise DirIsNotEmpty(path) except readfile.OffsetError: pass finally: closedir.closedir(fd) data_block_buffer.load(bn) filerecord.remove_file_record(offset) dir_inodetable_block.set_field(dir_table_in, dir_inodetable_block.i_mtime, int(time.time())) inodebitmap.set_free_inode(inode_table_n) inodebitmap.inode_bitmap.unload( fs.bytes_to_int(bg_block.get_field(0, bg_block.bg_inode_bitmap))) inodetable.unload_inode(inode_n) inodetable.unload_inode(dir_in) inodetable.unload_inode(0) data_block_buffer.unload(data_block_buffer.block_number)