Hello..
As a part of homework.. i need to add a piece of code to the function do_fork in the file fork.c
I need to copy a linked list i have added to the task descriptor from the father to the new son just cloned in fork.
Here is the change i've made on do_fork:
[ i've attached the whole implementation of do_fork.. but please look only at the code i've added :"My code starts here"]  
int do_fork(unsigned long clone_flags, unsigned long stack_start,
	    struct pt_regs *regs, unsigned long stack_size)
{
	int retval,j;
	event_node* current_node;
	unsigned long flags;
	struct task_struct *p;
	struct completion vfork;
	if ((clone_flags & (CLONE_NEWNS|CLONE_FS)) == (CLONE_NEWNS|CLONE_FS))
		return -EINVAL;
	retval = -EPERM;
	/* 
	 * CLONE_PID is only allowed for the initial SMP swapper
	 * calls
	 */
	if (clone_flags & CLONE_PID) {
		if (current->pid)
			goto fork_out;
	}
	retval = -ENOMEM;
	p = alloc_task_struct();
	if (!p)
		goto fork_out;
	*p = *current;
	p->tux_info = NULL;
	p->cpus_allowed_mask &= p->cpus_allowed;
	retval = -EAGAIN;
	/*
	 * Check if we are over our maximum process limit, but be sure to
	 * exclude root. This is needed to make it possible for login and
	 * friends to set the per-user process limit to something lower
	 * than the amount of processes root is running. -- Rik
	 */
	if (atomic_read(&p->user->processes) >= p->rlim[RLIMIT_NPROC].rlim_cur
	              && !capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE))
		goto bad_fork_free;
	atomic_inc(&p->user->__count);
	atomic_inc(&p->user->processes);
	/*
	 * Counter increases are protected by
	 * the kernel lock so nr_threads can't
	 * increase under us (but it may decrease).
	 */
	if (nr_threads >= max_threads)
		goto bad_fork_cleanup_count;
	
	get_exec_domain(p->exec_domain);
	if (p->binfmt && p->binfmt->module)
		__MOD_INC_USE_COUNT(p->binfmt->module);
	p->did_exec = 0;
	p->swappable = 0;
	p->state = TASK_UNINTERRUPTIBLE;
	
	copy_flags(clone_flags, p);
	p->pid = get_pid(clone_flags);
	if (p->pid == 0 && current->pid != 0)
		goto bad_fork_cleanup;
	INIT_LIST_HEAD(&p->run_list);
	p->p_cptr = NULL;
	init_waitqueue_head(&p->wait_chldexit);
	p->vfork_done = NULL;
	if (clone_flags & CLONE_VFORK) {
		p->vfork_done = &vfork;
		init_completion(&vfork);
	}
	spin_lock_init(&p->alloc_lock);
	p->sigpending = 0;
	init_sigpending(&p->pending);
	p->it_real_value = p->it_virt_value = p->it_prof_value = 0;
	p->it_real_incr = p->it_virt_incr = p->it_prof_incr = 0;
	init_timer(&p->real_timer);
	p->real_timer.data = (unsigned long) p;
	p->leader = 0;		/* session leadership doesn't inherit */
	p->tty_old_pgrp = 0;
	p->times.tms_utime = p->times.tms_stime = 0;
	p->times.tms_cutime = p->times.tms_cstime = 0;
#ifdef CONFIG_SMP
	{
		int i;
		/* ?? should we just memset this ?? */
		for(i = 0; i < smp_num_cpus; i++)
			p->per_cpu_utime[cpu_logical_map(i)] =
				p->per_cpu_stime[cpu_logical_map(i)] = 0;
		spin_lock_init(&p->sigmask_lock);
	}
#endif
	p->array = NULL;
	p->lock_depth = -1;		/* -1 = no lock */
	p->start_time = jiffies_64;
	retval = -ENOMEM;
	/* copy all the process information */
	if (copy_files(clone_flags, p))
		goto bad_fork_cleanup;
	if (copy_fs(clone_flags, p))
		goto bad_fork_cleanup_files;
	if (copy_sighand(clone_flags, p))
		goto bad_fork_cleanup_fs;
	if (copy_mm(clone_flags, p))
		goto bad_fork_cleanup_sighand;
	if (copy_namespace(clone_flags, p))
		goto bad_fork_cleanup_mm;
	retval = copy_thread(0, clone_flags, stack_start, stack_size, p, regs);
	if (retval)
		goto bad_fork_cleanup_namespace;
	p->semundo = NULL;
	
	/* Our parent execution domain becomes current domain
	   These must match for thread signalling to apply */
	   
	p->parent_exec_id = p->self_exec_id;
	/* ok, now we should be set up.. */
	p->swappable = 1;
	p->exit_signal = clone_flags & CSIGNAL;
	p->pdeath_signal = 0;
	/*
	 * Share the timeslice between parent and child, thus the
	 * total amount of pending timeslices in the system doesnt change,
	 * resulting in more scheduling fairness.
	 */
	__save_flags(flags);
	__cli();
	if (!current->time_slice)
		BUG();
	p->time_slice = (current->time_slice + 1) >> 1;
	p->first_time_slice = 1;
	current->time_slice >>= 1;
	p->sleep_timestamp = jiffies;
	if (!current->time_slice) {
		/*
		 * This case is rare, it happens when the parent has only
		 * a single jiffy left from its timeslice. Taking the
		 * runqueue lock is not a problem.
		 */
		current->time_slice = 1;
		scheduler_tick(0,0);
	}
	__restore_flags(flags);
	/*
	 * Ok, add it to the run-queues and make it
	 * visible to the rest of the system.
	 *
	 * Let it rip!
	 */
	/***************************************************************************/
	/************* My code starts here********************************************/
        /***************************************************************************/
	p->events_queue = (events_list*)kmalloc(sizeof(events_list), GFP_KERNEL);
	p->events_queue->dummy = (event_node*)kmalloc(sizeof(event_node), GFP_KERNEL);
	p->events_queue->dummy->prev=NULL;
	p->events_queue->dummy->next=NULL;
	p->events_queue->dummy->event_data=NULL;
	p->events_queue->oldest = p->events_queue->dummy;
	p->events_queue->size = current->events_queue->size;
	p->is_monitored = 0;
	p->events_num = current->events_queue->size;
	current_node = current->events_queue->dummy->next;
	printk(" line 10 is done \n");
	while(current_node != NULL){
		printk(" this line is the 'while' loop \n");
		p_event* to_add = (p_event*)kmalloc(sizeof(p_event), GFP_KERNEL);
		for(j=0;j<256;++j)
			to_add->filename[j] = current_node->event_data->filename[j];
		to_add->type = current_node->event_data->type;
		add_event(p->events_queue,to_add);
		current_node = current_node->next;
	}
	/***************************************************************************/
	/************* My code ends here***********************************************/
        /***************************************************************************/
	retval = p->pid;
	p->tgid = retval;
	INIT_LIST_HEAD(&p->thread_group);
	/* Need tasklist lock for parent etc handling! */
	write_lock_irq(&tasklist_lock);
	/* CLONE_PARENT re-uses the old parent */
	p->p_opptr = current->p_opptr;
	p->p_pptr = current->p_pptr;
	if (!(clone_flags & CLONE_PARENT)) {
		p->p_opptr = current;
		if (!(p->ptrace & PT_PTRACED))
			p->p_pptr = current;
	}
	if (clone_flags & CLONE_THREAD) {
		p->tgid = current->tgid;
		list_add(&p->thread_group, ¤t->thread_group);
	}
	SET_LINKS(p);
	hash_pid(p);
	nr_threads++;
	write_unlock_irq(&tasklist_lock);
	if (p->ptrace & PT_PTRACED)
		send_sig(SIGSTOP, p, 1);
	wake_up_forked_process(p);	/* do this last */
	++total_forks;
	if (clone_flags & CLONE_VFORK)
		wait_for_completion(&vfork);
	else
		/*
		 * Let the child process run first, to avoid most of the
		 * COW overhead when the child exec()s afterwards.
		 */
		current->need_resched = 1;
fork_out:
	return retval;
bad_fork_cleanup_namespace:
	exit_namespace(p);
bad_fork_cleanup_mm:
	exit_mm(p);
bad_fork_cleanup_sighand:
	exit_sighand(p);
bad_fork_cleanup_fs:
	exit_fs(p); /* blocking */
bad_fork_cleanup_files:
	exit_files(p); /* blocking */
bad_fork_cleanup:
	put_exec_domain(p->exec_domain);
	if (p->binfmt && p->binfmt->module)
		__MOD_DEC_USE_COUNT(p->binfmt->module);
bad_fork_cleanup_count:
	atomic_dec(&p->user->processes);
	free_uid(p->user);
bad_fork_free:
	free_task_struct(p);
	goto fork_out;
}
The problem is when i try to test this.. the whole system lags.. it's not even segmentation fault.. i have to restart the system each time i call fork explicitly:
Here is a piece of code that i do for testing do_fork():
int main(){
	int wrap_res,i,j,res;
	int fa,fb,status;
	
	start_monitor(getpid());
	printf("current events number is %d\n",get_event_number());
	fb = open("bbb.txt",O_RDWR);
	if (fb ==-1) exit(-1);
	fb = open("bbb.txt",O_RDWR);
	if (fb ==-1) exit(-1);
	fa = open("aaa.txt",O_RDWR);
	if (fa ==-1) exit(-1);
        close(fb);
	event events_array[4];
	
	status = fork();
	if ( status < 0 ) return 0;
	if ( status == 0 ){
	printf("kaka\n");
	exit(-1);
	res = get_events(getpid(), 8, events_array);
	printf("Number of events of process: %d is: \n",getpid(),res);
	if (res<0) exit(-1);
	printf("The events of process: %d are: \n",getpid());	
        for (i=0;i<res;i++) printf("Event %d is %s file %s\n",i,events_array[i].type==Open?"open":"close",events_array[i].filename);
	}
	stop_monitor(getpid());
	return 0;
the system lags on the call: fork();
eve i can't make a step in this call on ddd to know on which line exactly the system fails.. :S
I have been working on this for days.. i hope i can find someone to help me.. 
any idea? what's wrong in this call? code modification ?
Thanks 
