Beispiel #1
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 #2
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 #3
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
Beispiel #4
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 #5
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 #6
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)