Esempio n. 1
0
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)
Esempio n. 2
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)))
Esempio n. 3
0
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
Esempio n. 4
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
Esempio n. 5
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
Esempio n. 6
0
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
Esempio n. 7
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))
Esempio n. 8
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
Esempio n. 9
0
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)
Esempio n. 10
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)
Esempio n. 11
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)
Esempio n. 12
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)
Esempio n. 13
0
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
Esempio n. 14
0
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
Esempio n. 15
0
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
Esempio n. 16
0
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)
Esempio n. 17
0
def get_record_inode_number(offset):
    return fs.bytes_to_int(data_block_buffer.get_bytes(offset, IN_FIELD_SIZE))
Esempio n. 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]
Esempio n. 19
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)
Esempio n. 20
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)
Esempio n. 21
0
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]
Esempio n. 22
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))
Esempio n. 23
0
 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)
Esempio n. 24
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
Esempio n. 25
0
def get_group_number(number):
    return number // fs.bytes_to_int(superblock.get_field(superblock.s_inodes_per_group))
Esempio n. 26
0
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]
Esempio n. 27
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)