//************************************************************************** int my_open(struct inode* inode, struct file* filp) { filp->f_op = &fops; int minor = get_minor_from_inode(inode); filp->private_data = kmalloc(sizeof(device_private_data), GFP_KERNEL); if (filp->private_data == NULL) { return -ENOMEM; } device_private_data* data = (device_private_data*)(filp->private_data); data->minor = minor; data->private_key = iKey; //Update counters: spin_lock(counters_lock[minor]); if (is_reader(filp)) { num_of_readers[minor]++; } if (is_writer(filp)) { num_of_writers[minor]++; } spin_unlock(counters_lock[minor]); return 0; }
size_type size() const { return (is_open() ? (is_reader() ? __succinct_trie->size() : __succinct_writer->size()) : size_type(0)); }
/* * Alon: This function should write the buffer given by the user into the file. * The function assumes the given buffer is encrypted, and will therefor * use the iKey to decypher each character before writing it to the file. * The function returns the amount of bytes it managed to write into the * file, and -1 in case of failure. */ ssize_t my_write(struct file *filp, const char *buf, size_t count, loff_t *f_pos) { if(check_buffer_size(count) != 0) { return -EINVAL; } int minor = get_minor_from_file(filp); int is_this_process_reader = is_reader(filp); int key = ((device_private_data *)((filp)->private_data))->private_key; down_interruptible(&write_lock[minor]); down_interruptible(&index_lock[minor]); int maxToWrite = get_max_to_write(minor); if (maxToWrite == 0) { int current_num_of_readers = get_current_num_of_readers(minor); if(current_num_of_readers == is_this_process_reader) { up(&index_lock[minor]); up(&write_lock[minor]); return 0; } //Going to sleep until a reader clears some room in the buffer up(&index_lock[minor]); int wake_up_reason = wait_event_interruptible(write_wq[minor], flag_is_full[minor] == 0 || get_current_num_of_readers(minor) == is_this_process_reader); if(wake_up_reason != 0) { up(&write_lock[minor]); return -EINTR; } if (get_current_num_of_readers(minor) == is_this_process_reader) { up(&write_lock[minor]); return 0; } down_interruptible(&index_lock[minor]); maxToWrite = get_max_to_write(minor); } int numToWrite = MIN(maxToWrite,count); int firstPartSize = 0; int retval = 0; char* tmpBuf =(char*)kmalloc(sizeof(char)*numToWrite,GFP_KERNEL); if (!tmpBuf){ up(&index_lock[minor]); up(&write_lock[minor]); return -ENOMEM; } retval = copy_from_user(tmpBuf, buf, numToWrite); //copy the data from user if(retval != 0){ kfree(tmpBuf); up(&index_lock[minor]); up(&write_lock[minor]); return retval; } int numOfParts = ( (writing_position[minor] + numToWrite) > BUF_SIZE) ? TWO : ONE ; if(numOfParts == ONE ) { if (minor == 1) { encryptor(tmpBuf, &buffer[minor][writing_position[minor]], numToWrite, key, minor); } else if(minor == 0){ memcpy(&buffer[minor][ writing_position[minor] ], tmpBuf, numToWrite); } writing_position[minor] = (writing_position[minor] + numToWrite) % BUF_SIZE; } else { firstPartSize = BUF_SIZE - writing_position[minor]; if (minor == 1) { encryptor(tmpBuf, &buffer[minor][writing_position[minor]], firstPartSize, key, minor); encryptor(tmpBuf + firstPartSize, &buffer[minor][0], numToWrite - firstPartSize, key, minor); } else if (minor == 0) { memcpy(&buffer[minor][writing_position[minor]], tmpBuf, firstPartSize); memcpy(&buffer[minor][0], tmpBuf + firstPartSize, numToWrite - firstPartSize); } writing_position[minor] = (numToWrite - firstPartSize); } if(( writing_position[minor] == reading_position[minor]) && numToWrite){ flag_is_full[minor] = 1; } if (numToWrite) { flag_is_empty[minor] = 0; wake_up_interruptible(&read_wq[minor]); } /* * If we wrote something into the buffer, this makes sure to wake up * any writer who may be waiting for input. */ kfree(tmpBuf); up(&index_lock[minor]); up(&write_lock[minor]); if(retval != 0){ return retval; } return numToWrite; }