Beispiel #1
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)
Beispiel #2
0
def create_inode_table():
    first_data_block = fs.bytes_to_int(
        superblock.get_field(superblock.s_first_data_block))
    inodetable_block = inodetable.load_inode(0)
    table_number = inodetable.get_table_number(0)
    inodetable_block.set_field(
        table_number, inodetable_block.i_mode, inodetable.S_IFDIR
        | inodetable.S_IXUSR | inodetable.S_IRUSR | inodetable.S_IWUSR
        | inodetable.S_IXOTH | inodetable.S_IROTH | inodetable.S_IWOTH
        | inodetable.S_IWGRP
        | inodetable.S_IRGRP | inodetable.S_IXGRP)
    inodetable_block.set_field(table_number, inodetable_block.i_uid, 0)
    inodetable_block.set_field(table_number, inodetable_block.i_size, 0)
    inodetable_block.set_field(table_number, inodetable_block.i_atime, 0)
    inodetable_block.set_field(table_number, inodetable_block.i_mtime, 0)
    inodetable_block.set_field(table_number, inodetable_block.i_ctime,
                               int(time.time()))
    inodetable_block.set_field(table_number, inodetable_block.i_dtime, 0)
    inodetable_block.set_field(table_number, inodetable_block.i_gid, 0)
    inodetable_block.set_field(table_number, inodetable_block.i_blocks, 1)
    inodetable_block.set_field(table_number, inodetable_block.i_flags, 0)
    block = bytearray(inodetable_block.i_block[sysblock.SIZE_INDEX])
    block[:superblock.s_first_data_block[sysblock.SIZE_INDEX]] = \
        first_data_block.to_bytes(superblock.s_first_data_block[sysblock.SIZE_INDEX], 'little')
    inodetable_block.set_field(table_number, inodetable_block.i_block,
                               bytes(block))
    inodetable_block.set_field(
        table_number, inodetable_block.i_pad,
        bytes(inodetable_block.i_pad[sysblock.SIZE_INDEX]))
    inodetable.unload_inode(0)
Beispiel #3
0
 def _check_index(self, index):
     if self.offset_bn + (index * self.struct_size //
                          (fs.bytes_to_int(superblock.get_field(superblock.s_log_block_size)) * 1024)) \
        != self.block_buffer_bn:
         raise IndexError(
             "Can't read structure #{0} in this block. Offset: {1}. Block number: {2}"
             .format(index, self.offset_bn, self.block_buffer_bn))
Beispiel #4
0
def create_gdtable(group_number):
    gdtable.load_gdtable(group_number)
    block_size = fs.bytes_to_int(
        superblock.get_field(superblock.s_log_block_size)) * 1024
    blocks_per_group = fs.bytes_to_int(
        superblock.get_field(superblock.s_blocks_per_group))
    inodes_per_group = fs.bytes_to_int(
        superblock.get_field(superblock.s_inodes_per_group))
    groups_count = fs.get_groups_count(
        fs.bytes_to_int(superblock.get_field(superblock.s_blocks_count)),
        fs.bytes_to_int(superblock.get_field(superblock.s_blocks_per_group)))
    gdtable_blocks_count = math.ceil(groups_count * fs.GD_SIZE / block_size)
    itable_blocks_count = math.ceil(inodes_per_group * fs.INODE_SIZE /
                                    block_size)

    for g in range(groups_count):
        gdtable_block = gdtable.get_gdtableblock(g)
        gdtable_block.set_field(
            g, gdtable_block.bg_block_bitmap,
            g * blocks_per_group + gdtable_blocks_count + 1)
        gdtable_block.set_field(
            g, gdtable_block.bg_inode_bitmap,
            g * blocks_per_group + gdtable_blocks_count + 2)
        gdtable_block.set_field(
            g, gdtable_block.bg_inode_table,
            g * blocks_per_group + gdtable_blocks_count + 3)
        if g == 0:
            gdtable_block.set_field(
                g, gdtable_block.bg_free_blocks_count, blocks_per_group -
                gdtable_blocks_count - itable_blocks_count - 4)
            gdtable_block.set_field(g, gdtable_block.bg_free_inodes_count,
                                    inodes_per_group - 1)
            gdtable_block.set_field(g, gdtable_block.bg_used_dirs_count, 1)
        else:
            gdtable_block.set_field(
                g, gdtable_block.bg_free_blocks_count, blocks_per_group -
                gdtable_blocks_count - itable_blocks_count - 3)
            gdtable_block.set_field(g, gdtable_block.bg_free_inodes_count,
                                    inodes_per_group)
            gdtable_block.set_field(g, gdtable_block.bg_used_dirs_count, 0)

        gdtable_block.set_field(
            g, gdtable_block.bg_pad,
            bytes(gdtable_block.bg_pad[sysblock.SIZE_INDEX]))

    gdtable.unload_gdtable(group_number)
Beispiel #5
0
def unload_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.unload(bn + group_bn + 1)
Beispiel #6
0
    def set_field(self, index, field, value):
        self._check_index(index)
        index %= fs.bytes_to_int(
            superblock.get_field(
                superblock.s_log_block_size)) * 1024 // self.struct_size

        self.block_buffer[index * self.struct_size + field[OFFSET_INDEX]:
                          index * self.struct_size + field[OFFSET_INDEX] + field[SIZE_INDEX]] = \
                          sysblock.to_bytes(value, field[SIZE_INDEX])
Beispiel #7
0
    def get_field(self, index, field):
        self._check_index(index)
        index %= fs.bytes_to_int(
            superblock.get_field(
                superblock.s_log_block_size)) * 1024 // self.struct_size

        return self.block_buffer[index * self.struct_size +
                                 field[OFFSET_INDEX]:index * self.struct_size +
                                 field[OFFSET_INDEX] + field[SIZE_INDEX]]
Beispiel #8
0
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
Beispiel #9
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))
Beispiel #10
0
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
Beispiel #11
0
def create_inode_bitmap(group_number):
    bitmap_bytes_count = math.ceil(
        fs.bytes_to_int(superblock.get_field(superblock.s_inodes_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_inode_bitmap))

    inodebitmap.inode_bitmap.load(bitmap_bn)
    inodebitmap.inode_bitmap.block_buffer[:bitmap_bytes_count] = bytes(
        bitmap_bytes_count)

    if group_number == 0:
        inodebitmap.inode_bitmap.block_buffer[:1] = b'\x01'

    inodebitmap.inode_bitmap.unload(bitmap_bn)
Beispiel #12
0
def write_by_offset(fd, buf, 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))
    blocks_count = fs.bytes_to_int(
        file_inodetable_block.get_field(inode_tn,
                                        file_inodetable_block.i_blocks))
    block_size = fs.bytes_to_int(
        superblock.get_field(superblock.s_log_block_size)) * 1024

    lbn = offset // block_size
    b_offset = offset % block_size

    if offset + nbytes > file_size:
        if b_offset + nbytes > block_size or lbn == blocks_count:
            inodetable.extend_file_blocks(file_inodetable_block, inode,
                                          i_block)
        file_inodetable_block.set_field(inode_tn, file_inodetable_block.i_size,
                                        offset + nbytes)

    bn = inodetable.lbn_to_bn(lbn, i_block)
    data_block_buffer.load(bn)
    if b_offset + nbytes > block_size:
        first_bytes_count = block_size - b_offset
        if first_bytes_count != 0:
            data_block_buffer.set_bytes(b_offset, buf[:first_bytes_count])
            data_block_buffer.unload(bn)
        bn = inodetable.lbn_to_bn(lbn + 1, i_block)
        data_block_buffer.load(bn)
        data_block_buffer.set_bytes(0, buf[first_bytes_count:nbytes])
    else:
        data_block_buffer.set_bytes(b_offset, buf)
    data_block_buffer.unload(bn)

    fdtable.set_offset(fd, offset + nbytes)

    file_inodetable_block.set_field(inode_tn, file_inodetable_block.i_mtime,
                                    int(time.time()))

    inodetable.unload_inode(inode)
Beispiel #13
0
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)))
Beispiel #14
0
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)
Beispiel #15
0
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)
Beispiel #16
0
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)
Beispiel #17
0
 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))
Beispiel #18
0
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]
Beispiel #19
0
def get_group_number(number):
    return number // fs.bytes_to_int(superblock.get_field(superblock.s_inodes_per_group))