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_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 #3
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 #4
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 #5
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 #6
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 #7
0
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)
Beispiel #8
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 #9
0
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)