mirror of
				https://github.com/torvalds/linux.git
				synced 2025-10-31 16:48:26 +02:00 
			
		
		
		
	switch timerfd compat syscalls to COMPAT_SYSCALL_DEFINE
... and move them over to fs/timerfd.c. Cleaner and easier that way... Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
		
							parent
							
								
									90caf58dad
								
							
						
					
					
						commit
						9d94b9e2f3
					
				
					 2 changed files with 66 additions and 60 deletions
				
			
		
							
								
								
									
										41
									
								
								fs/compat.c
									
									
									
									
									
								
							
							
						
						
									
										41
									
								
								fs/compat.c
									
									
									
									
									
								
							|  | @ -1737,47 +1737,6 @@ asmlinkage long compat_sys_signalfd(int ufd, | |||
| } | ||||
| #endif /* CONFIG_SIGNALFD */ | ||||
| 
 | ||||
| #ifdef CONFIG_TIMERFD | ||||
| 
 | ||||
| asmlinkage long compat_sys_timerfd_settime(int ufd, int flags, | ||||
| 				   const struct compat_itimerspec __user *utmr, | ||||
| 				   struct compat_itimerspec __user *otmr) | ||||
| { | ||||
| 	int error; | ||||
| 	struct itimerspec t; | ||||
| 	struct itimerspec __user *ut; | ||||
| 
 | ||||
| 	if (get_compat_itimerspec(&t, utmr)) | ||||
| 		return -EFAULT; | ||||
| 	ut = compat_alloc_user_space(2 * sizeof(struct itimerspec)); | ||||
| 	if (copy_to_user(&ut[0], &t, sizeof(t))) | ||||
| 		return -EFAULT; | ||||
| 	error = sys_timerfd_settime(ufd, flags, &ut[0], &ut[1]); | ||||
| 	if (!error && otmr) | ||||
| 		error = (copy_from_user(&t, &ut[1], sizeof(struct itimerspec)) || | ||||
| 			 put_compat_itimerspec(otmr, &t)) ? -EFAULT: 0; | ||||
| 
 | ||||
| 	return error; | ||||
| } | ||||
| 
 | ||||
| asmlinkage long compat_sys_timerfd_gettime(int ufd, | ||||
| 				   struct compat_itimerspec __user *otmr) | ||||
| { | ||||
| 	int error; | ||||
| 	struct itimerspec t; | ||||
| 	struct itimerspec __user *ut; | ||||
| 
 | ||||
| 	ut = compat_alloc_user_space(sizeof(struct itimerspec)); | ||||
| 	error = sys_timerfd_gettime(ufd, ut); | ||||
| 	if (!error) | ||||
| 		error = (copy_from_user(&t, ut, sizeof(struct itimerspec)) || | ||||
| 			 put_compat_itimerspec(otmr, &t)) ? -EFAULT: 0; | ||||
| 
 | ||||
| 	return error; | ||||
| } | ||||
| 
 | ||||
| #endif /* CONFIG_TIMERFD */ | ||||
| 
 | ||||
| #ifdef CONFIG_FHANDLE | ||||
| /*
 | ||||
|  * Exactly like fs/open.c:sys_open_by_handle_at(), except that it | ||||
|  |  | |||
							
								
								
									
										85
									
								
								fs/timerfd.c
									
									
									
									
									
								
							
							
						
						
									
										85
									
								
								fs/timerfd.c
									
									
									
									
									
								
							|  | @ -22,6 +22,7 @@ | |||
| #include <linux/anon_inodes.h> | ||||
| #include <linux/timerfd.h> | ||||
| #include <linux/syscalls.h> | ||||
| #include <linux/compat.h> | ||||
| #include <linux/rcupdate.h> | ||||
| 
 | ||||
| struct timerfd_ctx { | ||||
|  | @ -278,21 +279,17 @@ SYSCALL_DEFINE2(timerfd_create, int, clockid, int, flags) | |||
| 	return ufd; | ||||
| } | ||||
| 
 | ||||
| SYSCALL_DEFINE4(timerfd_settime, int, ufd, int, flags, | ||||
| 		const struct itimerspec __user *, utmr, | ||||
| 		struct itimerspec __user *, otmr) | ||||
| static int do_timerfd_settime(int ufd, int flags,  | ||||
| 		const struct itimerspec *new, | ||||
| 		struct itimerspec *old) | ||||
| { | ||||
| 	struct fd f; | ||||
| 	struct timerfd_ctx *ctx; | ||||
| 	struct itimerspec ktmr, kotmr; | ||||
| 	int ret; | ||||
| 
 | ||||
| 	if (copy_from_user(&ktmr, utmr, sizeof(ktmr))) | ||||
| 		return -EFAULT; | ||||
| 
 | ||||
| 	if ((flags & ~TFD_SETTIME_FLAGS) || | ||||
| 	    !timespec_valid(&ktmr.it_value) || | ||||
| 	    !timespec_valid(&ktmr.it_interval)) | ||||
| 	    !timespec_valid(&new->it_value) || | ||||
| 	    !timespec_valid(&new->it_interval)) | ||||
| 		return -EINVAL; | ||||
| 
 | ||||
| 	ret = timerfd_fget(ufd, &f); | ||||
|  | @ -323,27 +320,23 @@ SYSCALL_DEFINE4(timerfd_settime, int, ufd, int, flags, | |||
| 	if (ctx->expired && ctx->tintv.tv64) | ||||
| 		hrtimer_forward_now(&ctx->tmr, ctx->tintv); | ||||
| 
 | ||||
| 	kotmr.it_value = ktime_to_timespec(timerfd_get_remaining(ctx)); | ||||
| 	kotmr.it_interval = ktime_to_timespec(ctx->tintv); | ||||
| 	old->it_value = ktime_to_timespec(timerfd_get_remaining(ctx)); | ||||
| 	old->it_interval = ktime_to_timespec(ctx->tintv); | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Re-program the timer to the new value ... | ||||
| 	 */ | ||||
| 	ret = timerfd_setup(ctx, flags, &ktmr); | ||||
| 	ret = timerfd_setup(ctx, flags, new); | ||||
| 
 | ||||
| 	spin_unlock_irq(&ctx->wqh.lock); | ||||
| 	fdput(f); | ||||
| 	if (otmr && copy_to_user(otmr, &kotmr, sizeof(kotmr))) | ||||
| 		return -EFAULT; | ||||
| 
 | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| SYSCALL_DEFINE2(timerfd_gettime, int, ufd, struct itimerspec __user *, otmr) | ||||
| static int do_timerfd_gettime(int ufd, struct itimerspec *t) | ||||
| { | ||||
| 	struct fd f; | ||||
| 	struct timerfd_ctx *ctx; | ||||
| 	struct itimerspec kotmr; | ||||
| 	int ret = timerfd_fget(ufd, &f); | ||||
| 	if (ret) | ||||
| 		return ret; | ||||
|  | @ -356,11 +349,65 @@ SYSCALL_DEFINE2(timerfd_gettime, int, ufd, struct itimerspec __user *, otmr) | |||
| 			hrtimer_forward_now(&ctx->tmr, ctx->tintv) - 1; | ||||
| 		hrtimer_restart(&ctx->tmr); | ||||
| 	} | ||||
| 	kotmr.it_value = ktime_to_timespec(timerfd_get_remaining(ctx)); | ||||
| 	kotmr.it_interval = ktime_to_timespec(ctx->tintv); | ||||
| 	t->it_value = ktime_to_timespec(timerfd_get_remaining(ctx)); | ||||
| 	t->it_interval = ktime_to_timespec(ctx->tintv); | ||||
| 	spin_unlock_irq(&ctx->wqh.lock); | ||||
| 	fdput(f); | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| SYSCALL_DEFINE4(timerfd_settime, int, ufd, int, flags, | ||||
| 		const struct itimerspec __user *, utmr, | ||||
| 		struct itimerspec __user *, otmr) | ||||
| { | ||||
| 	struct itimerspec new, old; | ||||
| 	int ret; | ||||
| 
 | ||||
| 	if (copy_from_user(&new, utmr, sizeof(new))) | ||||
| 		return -EFAULT; | ||||
| 	ret = do_timerfd_settime(ufd, flags, &new, &old); | ||||
| 	if (ret) | ||||
| 		return ret; | ||||
| 	if (otmr && copy_to_user(otmr, &old, sizeof(old))) | ||||
| 		return -EFAULT; | ||||
| 
 | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| SYSCALL_DEFINE2(timerfd_gettime, int, ufd, struct itimerspec __user *, otmr) | ||||
| { | ||||
| 	struct itimerspec kotmr; | ||||
| 	int ret = do_timerfd_gettime(ufd, &kotmr); | ||||
| 	if (ret) | ||||
| 		return ret; | ||||
| 	return copy_to_user(otmr, &kotmr, sizeof(kotmr)) ? -EFAULT: 0; | ||||
| } | ||||
| 
 | ||||
| #ifdef COMPAT | ||||
| COMPAT_SYSCALL_DEFINE4(timerfd_settime, int, ufd, int, flags, | ||||
| 		const struct itimerspec __user *, utmr, | ||||
| 		struct itimerspec __user *, otmr) | ||||
| { | ||||
| 	struct itimerspec new, old; | ||||
| 	int ret; | ||||
| 
 | ||||
| 	if (get_compat_itimerspec(&new, utmr)) | ||||
| 		return -EFAULT; | ||||
| 	ret = do_timerfd_settime(ufd, flags, &new, &old); | ||||
| 	if (ret) | ||||
| 		return ret; | ||||
| 	if (otmr && put_compat_itimerspec(otmr, &old)) | ||||
| 		return -EFAULT; | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| COMPAT_SYSCALL_DEFINE2(timerfd_gettime, int, ufd, | ||||
| 		struct itimerspec __user *, otmr) | ||||
| { | ||||
| 	struct itimerspec kotmr; | ||||
| 	int ret = do_timerfd_gettime(ufd, &kotmr); | ||||
| 	if (ret) | ||||
| 		return ret; | ||||
| 	return put_compat_itimerspec(otmr, &t) ? -EFAULT: 0; | ||||
| } | ||||
| #endif | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Al Viro
						Al Viro