/* * Attaches BitMap to memory mapped file that is created in indices/ directory. * file name is based on nmap name, so bit map name should be valid linux file * name. * * File is created immidietly and space is allocated to match requested bit map * size. Previously allocated bit map space is freed without copying it! */ BitMap bm_attach_to_file(BitMap self) { int fname_length = strlen(self->name) + 8 + 4 + 1; // length of 'indices/' + length of '.idx' + 1 for 0 char* fname = malloc(fname_length); struct stat buffer; int fsize = self->part_length * sizeof (BitMapPart); sprintf(fname, "indices/%s.idx", self->name); if (self->parts) free(self->parts); try_io(self->fd = open(fname, O_RDWR | O_CREAT | O_TRUNC, 0600)); try_io(fstat(self->fd, &buffer)); if (buffer.st_size < fsize) { try_io(lseek(self->fd, fsize - 1, SEEK_SET)); try_io(write(self->fd, "\0", 1)); } try_io(self->parts = mmap(NULL, fsize, PROT_WRITE | PROT_READ, MAP_SHARED, self->fd, 0)); free(fname); return (self); }
/* * Resizes bitmap to new bit length. If bit length falls into same part length, * then nothing is changed besides bit_length. * * realloc and mremap are used - both claim to copy data, but they might change * address of parts pointer. Becouse of that, client should not store pointers * to arbitrary parts, instead store index of part relative to first part. * */ BitMap bm_resize(BitMap self, int new_bit_length) { int new_part_length = bm_part_length(new_bit_length); int new_byte_size = new_part_length * sizeof (BitMapPart); if (new_part_length != self->part_length) { if (self->persisted) { try_io(lseek(self->fd, new_byte_size - 1, SEEK_SET)); try_io(write(self->fd, "\0", 1)); self->parts = mremap( self->parts, self->part_length * sizeof (BitMapPart), new_byte_size, MREMAP_MAYMOVE ); } else { self->parts = realloc(self->parts, new_byte_size); } } self->bit_length = new_bit_length; self->part_length = new_part_length; return (self); }
void priv_vfs_readwrite_fother(int asroot, int injail, struct test *test) { try_io("priv_vfs_readwrite_fother(none, O_RDONLY)", fpath_none, asroot, injail, O_RDONLY, asroot ? 0 : -1, EACCES); try_io("priv_vfs_readwrite_fother(none, O_WRONLY)", fpath_none, asroot, injail, O_WRONLY, asroot ? 0 : -1, EACCES); try_io("priv_vfs_readwrite_fother(none, O_RDWR)", fpath_none, asroot, injail, O_RDWR, asroot ? 0 : -1, EACCES); try_io("priv_vfs_readwrite_fother(read, O_RDONLY)", fpath_read, asroot, injail, O_RDONLY, 0, 0); try_io("priv_vfs_readwrite_fother(read, O_WRONLY)", fpath_read, asroot, injail, O_WRONLY, asroot ? 0 : -1, EACCES); try_io("priv_vfs_readwrite_fother(read, O_RDWR)", fpath_read, asroot, injail, O_RDWR, asroot ? 0 : -1, EACCES); try_io("priv_vfs_readwrite_fother(write, O_RDONLY)", fpath_write, asroot, injail, O_RDONLY, asroot ? 0 : -1, EACCES); try_io("priv_vfs_readwrite_fother(write, O_WRONLY)", fpath_write, asroot, injail, O_WRONLY, 0, 0); try_io("priv_vfs_readwrite_fother(write, O_RDWR)", fpath_write, asroot, injail, O_RDWR, asroot ? 0 : -1, EACCES); try_io("priv_vfs_readwrite_fother(write, O_RDONLY)", fpath_readwrite, asroot, injail, O_RDONLY, 0, 0); try_io("priv_vfs_readwrite_fother(write, O_WRONLY)", fpath_readwrite, asroot, injail, O_WRONLY, 0, 0); try_io("priv_vfs_readwrite_fother(write, O_RDWR)", fpath_readwrite, asroot, injail, O_RDWR, 0, 0); }